技術交流

Using ADODB with PHP and Oracle (Part II)

Dennis Dennis
站在巨人的肩膀上

在Using ADODB with PHP and Oracle (Part I) 中我們討論了用傳統方式連結到 Oracle Database 的方法和使用 ADODB 連結 Oracle Database 的方式的不同,從 Oracle Database 中取資料的方法 ( GetArray、GetAll、GetRow、GetOne )及模仿 MySQL limit 功能的 SelectLimit()方法。在本文中,我們將討論 ADODB 連 Oracle Database時如何Call Oracle Store Procedure 和 Functions。

開始之前,我們先列出 Oracle Database 中用 PL/SQL 撰寫的 Procedure 及 Function. 假定 Database Connection Handler 為 $DBConn (在後面的 PHP 代碼中有用到此變數)。


// Procedure 只有 in 參數
Procedure my_proec (p_in_param in varchar2)
Is
Begin
   // do something here
End;

// Procedure 有 out 參數
Procedure my_proec (p_in_param in varchar2 ,p_out_param out varchar2)
Is
Begin
  P_out_param :='This is input data->'|| p_in_param ;
End;

// Function
Function my_func (p_in_param in varchar2 ,p_out_param out varchar2) return number
Is
Begin
  P_out_param :='This is input data->'|| p_in_param ;
  Return 1;
End;

Call Oracle Store Procedure

ADODB 的 Oracle Driver 中專門針對 Oracle Database的特性撰寫了 Call Procedure 的方法。

在 Procedure 中如果沒有 out 參數,可以採用如下兩種方法來執行:

Execute

//PHP Code
$stmt = 'begin my_proc(:p_in_param); end;';
 $DBConn->Execute($stmt,array('p_in_param'=>' 這是輸入的資料'));
// 下面是從 eHR系統中摘錄出的程式代碼片段
 $stmt = 'begin 
pk_erp.p_set_segment_no(:companyid);pk_department.p_set_base_date(sys
date);pk_erp.p_set_username(:user_seq_no);end;';
 $this->DBConn->Execute($stmt, 
            array('companyid'=> $this->companyID,
               'user_seq_no'=>$user_seqno));

當用 Execute 方式來執行 Procedure時,在所要執行的 Procedure 前後要加上 “ begin … end; ”如上面的代碼片段。 所有的 PL/SQL Statement 必須在一行(如從eHR系統中摘錄出來的程式版片段),請不要在代碼中回車(也就是說不能有 return code)。可以執行多個 procedure,中間用分號隔開。

Prepare /Bind Variables/Execute

//PHP Code
$stmt1 = 'begin my_proc(:p_in_param); end;';
  $stmt = $DBConn->PrepareSP ( $stmt1 ); 
  $ DBConn->InParameter ( $stmt, '這是輸入的資料', 'p_in_param', 20 ); 
  //$DBConn->Execute($stmt); 
  // 如果在 Procedure中執行了 insert,update,delete,需要 commit 的,要加上
  // StartTrans()和 CompleteTrans() 的方法, 如下:
  //$DBConn->StartTrans (); // begin transaction
  $DBConn->Execute($stmt );
  //$DBConn->CompleteTrans (); // end transaction

使用bind variable 的方式來傳參數,用 ADODB 的 InParameter ( $stmt、 $var、 $name、 $maxLen = 4000、 $type = false ) 或 OutParamete r ( $stmt、 $var、 $name、 $maxLen = 4000、 $type = false )方法,參數說明: $stmt:經過PrepareSP()處理過的 PL/SQL Statement

  • $var:參數的值
  • $name:參數名稱
  • $maxLen:數據長度,default 4000

在 Procedure 中如果有 out 參數時,必須使用上述方式的第二種。因為有輸出的值,所以在 PHP 代碼中必須 declare 一個變數來存放輸出的值。


// 摘錄自 her系統中的代碼片段
$_submit_result = array ("days" => "", "hours" => "", "msg" => "",
"is_success" => "" );
  $stmt1 = "begin begin pk_erp.p_set_segment_no(:in_company_id1);  
end; begin pk_erp.p_set_username(:in_user_seqno); end; begin wf.pkg_work_flow.p_submit_absence_apply(pi_seg_segment_no=>:in_compan
yid,pi_absence_flow_sz_id=>:in_workflow_seqno,po_days=>:out_days,po_h
ours=>:out_hours,po_errmsg=>:out_msg,po_success=>:out_issuccess); 
end;end;";
  $stmt = $this->DBConn->PrepareSP ( $stmt1 );
  $this->DBConn->InParameter ( $stmt, $companyid, 
"in_company_id1",10 );
  $this->DBConn->InParameter ( $stmt, $companyid,
"in_companyid", 10 );
  $this->DBConn->InParameter ( $stmt, $user_seqno,
"in_user_seqno", 10 );
  $this->DBConn->InParameter ( $stmt, $workflow_seqno,
"in_workflow_seqno", 10 );
  $this->DBConn->OutParameter ( $stmt, $_submit_result ["days"], 
"out_days", 5 );
  $this->DBConn->OutParameter ( $stmt, $_submit_result["hours"],
"out_hours", 6 );
$this->DBConn->OutParameter ( $stmt, $_submit_result ["msg"],
"out_msg", 2000 );
$this->DBConn->OutParameter ( $stmt, $_submit_result
["is_success"], "out_issuccess", 2 );
//$this->DBConn->debug = true;
$this->DBConn->StartTrans (); // begin transaction
$this->DBConn->Execute ( $stmt );
$this->DBConn->CompleteTrans (); // end transaction
return $_submit_result;

其它同上面的說明,值得一提的是,在代碼的開始 declare 了一個 array來存放多個 out 的變數(當你有多個out 參數時可以採用此方法,只有一個 out 參數,直接 declare一個變數賦初值就可以了)。

Call Oracle Store Function

Function 一定會有 return的值,所以跟 Procedure 的方式有所不同。

只有 In Parameter

當只有 In Parameter時問題就簡單的多了。因為有 function 有 return value,所以可利用標準的 SQL Select 來解決這個問題。


$sql = 'select my_func(:p_in_param) from dual';
 $outval = $DBConn->GetOne($sql,array('p_in_param'=>'some data'));
 Echo $outval;

當只有 In Parameter時,可以利用 Oracle Database 的 dual table,用 select 的方式來執行這個 function,然後用 ADODB 的 GetOne()來得到 function 執行的結果。

既有 In Parameter 也有 Out Parameter

限於篇幅,本期就介紹到此。既有 In Parameter 也有 Out Parameter 的方支將在下一期電子報中的 《Using ADODB with PHP and Oracle (Part III) 》 中介紹。