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

Reply via email to