【问题标题】:Call Oracle stored procedure from PHP从 PHP 调用 Oracle 存储过程
【发布时间】:2017-05-21 06:05:16
【问题描述】:

我正在尝试执行并从我的程序中获取数据:

这是我的程序的定义方式:

create or replace PROCEDURE SP_GET_MY_DATA(
         IN_POP VARCHAR2,
         IN_SEG VARCHAR2,
         IN_DUR VARCHAR2, 
         IN_VIEW INTEGER, 
         IN_PAGE INTEGER, 
         VIEW_DATA_CUR OUT SYS_REFCURSOR) AS ...

这是我的 PHP 代码,用于执行并从过程中获取数据:

$db = "(DESCRIPTION=(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = JXYX.com)(PORT = 1521)))(CONNECT_DATA=(SID=DHSJKS)))";
$conn = ocilogon("XXXXXX","XXXXXXXX",$db);          

$sql = 'BEGIN SP_GET_MY_DATA(:POP, :SEG, :DUR, :VIEW, :PAGE, :OUTPUT_CUR); END;';            

$stmt = oci_parse($conn,$sql);                     
oci_bind_by_name($stmt,':POP',$pop);           
oci_bind_by_name($stmt,':SEG',$seg);           
oci_bind_by_name($stmt,':DUR',$dur);           
oci_bind_by_name($stmt,':VIEW',$view);           
oci_bind_by_name($stmt,':PAGE',$page);           
$OUTPUT_CUR = oci_new_cursor($conn);
oci_bind_by_name($stmt,":OUTPUT_CUR", $OUTPUT_CUR, -1, OCI_B_CURSOR);                   
oci_execute($stmt, OCI_DEFAULT); 

while ($data = oci_fetch_assoc($OUTPUT_CUR)) {
    print_r($data);
}

但是这样做我得到了这个错误:

oci_fetch_assoc(): ORA-24374: define not done before fetch or execute and fetch”。

我无法弄清楚我错过了什么。你能帮忙吗?

【问题讨论】:

  • 执行$stmt后,还必须执行$OUTOUT_CUR

标签: php oracle


【解决方案1】:

与直接从SELECT 语句访问行相比,在 PHP 中使用游标需要三个额外的步骤。

  • 第一步是在 PHP 中使用 oci_new_cursor() 函数准备一个游标资源,然后您可以使用该函数绑定到适当的参数。
  • 第二步,在oci_bind_by_name()函数上加个参数
  • 第三步,在您执行完通常的 SQL 语句后,在游标资源上调用 oci_execute()

代码:

//Connection does not change
$db = "(DESCRIPTION=(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = JXYX.com)(PORT = 1521)))(CONNECT_DATA=(SID=DHSJKS)))";
$conn = ocilogon("XXXXXX","XXXXXXXX",$db);          

//Request does not change
$sql = 'BEGIN SP_GET_MY_DATA(:POP, :SEG, :DUR, :VIEW, :PAGE, :OUTPUT_CUR); END;';            

//Statement does not change
$stmt = oci_parse($conn,$sql);                     
oci_bind_by_name($stmt,':POP',$pop);           
oci_bind_by_name($stmt,':SEG',$seg);           
oci_bind_by_name($stmt,':DUR',$dur);           
oci_bind_by_name($stmt,':VIEW',$view);           
oci_bind_by_name($stmt,':PAGE',$page);    

//But BEFORE statement, Create your cursor
$cursor = oci_new_cursor($conn)

// On your code add the latest parameter to bind the cursor resource to the Oracle argument
oci_bind_by_name($stmt,":OUTPUT_CUR", $cursor,-1,OCI_B_CURSOR);

// Execute the statement as in your first try
oci_execute($stmt);

// and now, execute the cursor
oci_execute($cursor);

// Use OCIFetchinto in the same way as you would with SELECT
while ($data = oci_fetch_assoc($cursor, OCI_RETURN_LOBS )) {
    print_r($data);
}

我对 Oracle(和英语)不是很流利,所以您应该阅读 this tutorial。有一个有趣的例子,请看存储过程和引用游标一章!

希望对你有帮助!

【讨论】:

    【解决方案2】:

    本示例基于Oracle Documentation

    // Define MYDB connection string as described in tnsnames.ora
    define("MYDB","(DESCRIPTION=(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = JXYX.com)(PORT = 1521)))(CONNECT_DATA=(SID=DHSJKS)))");
    // Connect to database
    $conn = oci_connect("XXXXXX","XXXXXXXX",MYDB);  
    // Through error if not connected 
    if (!$conn) {
        $e = oci_error();
        trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
    }  
    // Bind the your input and output parameters to PHP variables                
    $stmt = oci_parse($conn,'BEGIN SP_GET_MY_DATA(:POP, :SEG, :DUR, :VIEW, :PAGE, :OUTPUT_CUR); END;');                     
    oci_bind_by_name($stmt,':POP',$pop);           
    oci_bind_by_name($stmt,':SEG',$seg);           
    oci_bind_by_name($stmt,':DUR',$dur);           
    oci_bind_by_name($stmt,':VIEW',$view);           
    oci_bind_by_name($stmt,':PAGE',$page);  
    // Declare your cursor         
    $OUTPUT_CUR = oci_new_cursor($conn);
    oci_bind_by_name($stmt,":OUTPUT_CUR", $OUTPUT_CUR, -1, OCI_B_CURSOR);    
    // Execute statement               
    oci_execute($stmt); 
    // Execute the cursor
    oci_execute($OUTPUT_CUR);
    // Fetch results
    while ($data = oci_fetch_assoc($OUTPUT_CUR)) {
        print_r($data);
    }
    

    【讨论】:

      猜你喜欢
      • 2011-03-13
      • 2011-04-25
      • 2015-05-22
      • 2012-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多