|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2007-10-03 15:39 UTC] pr0head at gmail dot com
Description:
------------
If you have two or more times the same stored procedure where the cursor name the same ( :cursor ), PHP stop work.
Reproduce code:
---------------
$connection = oci_connect( .... );
// First execute SP
$sql = "BEGIN sp_vadik_1( :cursor ); END;";
$stmt = oci_parse( $connection, $sql );
$cursor = oci_new_cursor( $connection );
oci_bind_by_name( $stmt, ":cursor", $cursor, -1, OCI_B_CURSOR );
oci_execute( $stmt, OCI_DEFAULT );
oci_execute( $cursor );
while( $row = oci_fetch_array( $cursor ) ) { .... }
oci_free_statement( $stmt );
oci_free_statement( $cursor );
Expected result:
----------------
If the cursor names are not different ( first - :cursor1, second - :cursor2), the challenges are successful.
If not cleaned cursor to the first call, and declare it in the second, the queries are also successful.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 15:00:01 2025 UTC |
<?php /** * ORACLE Storage Procedure * * create or replace procedure sp_vadik_1 ( out_1 out sys_refcursor ) is begin * open out_1 for select 11 from dual union all select 12 from dual union all select 13 from dual; * end sp_vadik_1; */ $params_db = array( 'host' => "localhost", 'username' => "username", 'password' => "password", 'dbname' => "db" ); putenv( 'ORACLE_SID=' . $params_db['dbname'] ); $conn_string = '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=' . $params_db['host'] . ')(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=' . $params_db['dbname'] . ')))'; $connection = @oci_connect( $params_db['username'], $params_db['password'], $conn_string ); //------------ START EXECUTE 1 ---------------// $sql = "BEGIN sp_vadik_1( :cursor ); END;"; $stmt = oci_parse( $connection, $sql ); $cursor = oci_new_cursor( $connection ); oci_bind_by_name( $stmt, ":cursor", $cursor, -1, OCI_B_CURSOR ); oci_execute( $stmt, OCI_DEFAULT ); oci_execute( $cursor ); while( $row = oci_fetch_array( $cursor, OCI_ASSOC + OCI_RETURN_LOBS ) ) { $data[] = $row; } oci_free_statement( $stmt ); oci_free_statement( $cursor ); //------------ STOP EXECUTE 1 ---------------// //------------ START EXECUTE 2 ---------------// $sql = "BEGIN sp_vadik_1( :cursor1 ); END;"; $stmt = oci_parse( $connection, $sql ); $cursor = oci_new_cursor( $connection ); oci_bind_by_name( $stmt, ":cursor1", $cursor, -1, OCI_B_CURSOR ); oci_execute( $stmt, OCI_DEFAULT ); oci_execute( $cursor ); while( $row = oci_fetch_array( $cursor, OCI_ASSOC + OCI_RETURN_LOBS ) ) { $data[] = $row; } oci_free_statement( $stmt ); oci_free_statement( $cursor ); var_dump($cur2); //------------ STOP EXECUTE 2 ---------------// oci_close( $connection ); ?>This was a latent bug exposed when statement caching was fixed. The temporary workaround is to set oci8.statement_cache_size=0 The real solution (thanks to Sree) is to add a missing case for cursors to the out-bind callback: diff -u oci8_statement.c.orig oci8_statement.c --- oci8_statement.c.orig 2008-01-30 10:37:32.000000000 -0800 +++ oci8_statement.c 2008-01-30 10:21:31.000000000 -0800 @@ -1174,6 +1174,14 @@ } if (Z_TYPE_P(val) == IS_RESOURCE) { + /* Processing for ref-cursor out binds */ + if (phpbind->statement != NULL) { + *bufpp = phpbind->statement; + *alenpp = &phpbind->dummy_len; + *piecep = OCI_ONE_PIECE; + *rcodepp = &phpbind->retcode; + *indpp = &phpbind->indicator; + } retval = OCI_CONTINUE; } else if (Z_TYPE_P(val) == IS_OBJECT) { if (!phpbind->descriptor) {