ID: 37209 Comment by: issvar at hotmail dot com Reported By: netvbonline at yahoo dot co dot uk Status: Assigned Bug Type: MSSQL related Operating System: Win XP Pro PHP Version: 5.1.2 Assigned To: fmk New Comment:
This is caused by php stopping processing when dbsqlok() returns FAIL. Microsoft db-library for c manual states that even if dbsqlok() returns FAIL there could be results, so results and return values and output parameters should be processed. So in ext/mssql/php_mssql.c there should be changed the following part in PHP_FUNCTION(mssql_execute): if (dbrpcexec(mssql_ptr->link)==FAIL || dbsqlok(mssql_ptr->link)==FAIL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "stored procedure execution failed"); dbcancel(mssql_ptr->link); RETURN_FALSE; } this should be changed to: if (dbrpcexec(mssql_ptr->link)==FAIL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "stored procedure execution failed"); dbcancel(mssql_ptr->link); RETURN_FALSE; } if (dbsqlok(mssql_ptr->link)==FAIL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "stored procedure execution failed"); } Previous Comments: ------------------------------------------------------------------------ [2006-07-27 00:03:22] [EMAIL PROTECTED] Frank, there's the feedback now. :) ------------------------------------------------------------------------ [2006-05-02 08:24:19] netvbonline at yahoo dot co dot uk * [Description] Procedure handles the process of either fetching or inserting a forename, this procedure must never update existing name otherwise it would affect all other person FK's */ CREATE PROCEDURE usp_fetch_or_insert_forename @Forename [varchar](50), @ForenameID [int] OUTPUT AS DECLARE @err int -- needed as the global @@ERROR is reset after each statement, even logical comparison -- reduce network traffic SET NOCOUNT ON -- first do common validation and checks BEGIN INSERT INTO [dbtest].[dbo].[Forename] ( [Forename] ) VALUES ( @Forename ) SET @err=@@ERROR print 'non fatal error ...' IF (@err = 2627) BEGIN RAISERROR('myMessage:test', 2, 1) WITH SETERROR END IF (@err=0) BEGIN -- explicitly retrieve the identity of row just inserted from above statement SET @ForenameID=SCOPE_IDENTITY() RETURN(0) END -- Test for key violation before returning error code IF (@err=2627 ) BEGIN print 'Looking up the forename value' -- I know the name exists, so fetch the PK SELECT @ForenameID=ForenameID FROM Forename WHERE [EMAIL PROTECTED] print 'still here .. and forenameid is ' + str(@ForenameID) RETURN(0) END -- There was an error in the insert statement, not related to unique key violation constraint so return error code RETURN(@err) END GO Hope this is ok, as you can see it contains various debug messages. ------------------------------------------------------------------------ [2006-04-29 03:13:35] [EMAIL PROTECTED] Please provide a short example of the procedure used to generate this. The current implementation will handle multiple results from a storred procedure and it will skip all results without column. ------------------------------------------------------------------------ [2006-04-26 14:34:02] netvbonline at yahoo dot co dot uk SORRY, BIG TYPO "The mssql_execute method SHOULD NOT fail on execution (but in anycase should still have populated output parameters)." ------------------------------------------------------------------------ [2006-04-26 14:32:23] netvbonline at yahoo dot co dot uk Description: ------------ Using the extension php_mssql.dll and mssql_execute method to execute a stored procedure within SQL Server 2000. Basically, if the stored procedure generates a non-fatal message, for example trying to insert a duplicate value into a table before doing a big seek then output parameters are still available to Query analyser. However when using the mssql_execute method, the execution fails.. even though stored procedure is returning a successful execution value of 0. Its possible to have a stored procedure with 10 statements, and 5 legitamately may fail with a non fatal message, which is handled internally by the stored procedure. The mssql_execute method should fail on execution (any in anycase should still have populated output parameters). Cheers. Reproduce code: --------------- $hStmt = mssql_init("usp_fetch_or_insert_forename", $hCon); mssql_bind($hStmt, "@Forename", $name, SQLVARCHAR); // Output mssql_bind($hStmt, "@ForenameID", $ForenameID, SQLINT4, TRUE); $result=mssql_execute($hStmt,true); if (!$result) { echo "ERROR HAS OCCURRED"; } else { echo "NO ERROR"; } if ($ForenameID==0) { // error must have occurred echo "There was an error trying to get forename pk and forenameid is ".$ForenameID; } else { echo "everything is fine and forenameid is ".$ForenameID; } Expected result: ---------------- $ForenameID=Value Returned From Stored Procedure Actual result: -------------- $ForenameID=0 ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=37209&edit=1