2010-06-01 40 views
3

我使用PHP和OCI8來執行匿名的Oracle PL/SQL代碼塊。有沒有什麼辦法讓我在完成塊的時候綁定一個變量並獲得它的輸出,就像我以類似的方式調用存儲過程時一樣?我可以從匿名PL/SQL塊返回值到PHP嗎?

$SQL = "declare 
something varchar2 := 'I want this returned'; 
begin 
    --How can I return the value of 'something' into a bound PHP variable? 
end;"; 

回答

2

您可以通過使用關鍵字的名稱和數據類型聲明之間OUT定義的輸出參數。 IE:

CREATE OR REPLACE PROCEDURE blah (OUT_PARAM_EXAMPLE OUT VARCHAR2) IS ... 

如果未指定,則默認爲IN。如果要使用參數作爲輸入和輸出,請使用:

CREATE OR REPLACE PROCEDURE blah (INOUT_PARAM_EXAMPLE IN OUT VARCHAR2) IS ... 

以下示例使用IN和OUT參數創建過程。然後執行程序並打印結果。

<?php 
    // Connect to database... 
    $c = oci_connect("hr", "hr_password", "localhost/XE"); 
    if (!$c) { 
     echo "Unable to connect: " . var_dump(oci_error()); 
     die(); 
    } 

    // Create database procedure... 
    $s = oci_parse($c, "create procedure proc1(p1 IN number, p2 OUT number) as " . 
        "begin" . 
        " p2 := p1 + 10;" . 
        "end;"); 
    oci_execute($s, OCI_DEFAULT); 

    // Call database procedure... 
    $in_var = 10; 
    $s = oci_parse($c, "begin proc1(:bind1, :bind2); end;"); 
    oci_bind_by_name($s, ":bind1", $in_var); 
    oci_bind_by_name($s, ":bind2", $out_var, 32); // 32 is the return length 
    oci_execute($s, OCI_DEFAULT); 
    echo "Procedure returned value: " . $out_var; 

    // Logoff from Oracle... 
    oci_free_statement($s); 
    oci_close($c); 
?> 

參考:

+0

存儲過程是永久創建還是僅爲此會話創建?我使用這個方法來接收我在數據庫中編譯的過程中的OUT參數(它看起來像是在做同樣的事情,除了首先創建過程)。我想避免在執行此代碼時在數據庫中創建任何永久對象。 – 2010-06-02 13:28:16

+0

@Renderlin:是的,orafaq.com的例子會創建存儲過程。您需要將存儲過程放入匿名PLSQL塊的DECLARE塊中,並在BEGIN/END部分創建'proc1(...')以便不創建該過程。 – 2010-06-02 14:40:24

+0

非常感謝...製作我的日子 – 2010-06-02 18:42:07

-1

這裏我決定:

function execute_procedure($procedure_name, array $params = array(), &$return_value = ''){ 
    $sql = " 
    DECLARE 
     ERROR_CODE  VARCHAR2(2000); 
     ERROR_MSG  VARCHAR2(2000); 
     RETURN_VALUE VARCHAR2(2000); 
    BEGIN "; 

    $c = $this->get_connection(); 

    $prms = array(); 
    foreach($params AS $key => $value) $prms[] = ":$key"; 
    $prms = implode(", ", $prms); 

    $sql .= ":RETURN_VALUE := ".$procedure_name."($prms);"; 
    $sql .= " END;"; 


    $s = oci_parse($c, $sql); 

    foreach($params AS $key => $value) 
    { 
     $type = SQLT_CHR; 
     if(is_array($value)) 
     { 
      if(!isset($value['value'])) continue; 
      if(!empty($value['type'])) $type = $value['type']; 
      $value = $value['value']; 
     } 
     oci_bind_by_name($s, ":$key", $value, -1, $type); 
    } 

    oci_bind_by_name($s, ":RETURN_VALUE", $return_value, 2000); 

    try{ 
     oci_execute($s); 
     if(!empty($ERROR_MSG)) 
     { 
      $data['success'] = FALSE; 
      $this->errors = "Ошибка: $ERROR_CODE $ERROR_MSG"; 
     } 
     return TRUE; 
    } 
    catch(ErrorException $e) 
    { 
     $this->errors = $e->getMessage(); 
     return FALSE; 
    } 
} 

例如:

execute_procedure('My_procedure', array('code' => 5454215), $return_value); 
    echo $return_value; 
+0

傾銷一段代碼我很難考慮一個有價值的答案,請解釋爲什麼你的代碼解決了OP的問題。 – hotzst 2016-01-17 11:07:28

相關問題