因為工作的地方是用M$系列的,所以之前部門的開發就是用M$SQL的預儲程式(stored procedure)來執行與資料的讀取的動作,說真的,超不習慣的啦!雖然他們的立場是覺得stored procedure可以重複利用,可是我覺得這跟直接把SQL用刻在php程式碼裡,良好的設計(指物件寫法),也是可以重複利用呀,而且PHP可以用的函式又多,要去刻SQL也方便多了。如果硬是要說stored procedure好處,可能就是效能加快,安全性上升(有差那麼多嗎?個人不覺得)。

anyway...畢竟在工作的地方就是配合大家,所以我從google大仙去搜尋如何用PEAR::DB來呼叫已經寫好的預儲程式,不過相當殘念的,似乎這種文件非常少(>"<畢竟在php領域會用預儲程式去做資料庫存取的本來就很少),不過還是難得讓我找到這篇文章「Programming with SQL Relay using the PHP Pear DB API」。這篇文章把PEAR::DB所有連結資料庫與執行SQL的部分,做了滿多的範例,以下我就直接針對預儲程式的部分來說明(接下來的程式都是從文章擷錄而來)


Oracle作法

首頁先建立一個預儲程式如下

create procedure testproc(in1 in number, in2 in number, in3 in varchar2) is
begin
       insert into mytable values (in1,in2,in3);
end;

接下來直接用PEAR執行指定的預儲程式,並給予參數

$sth=$db->prepare("begin testproc(:in1,:in2,:in3); end;");
$bindvars=array("in1" => 1,
                "in2" => 1.1,
                "in3" => "hello"})
$res=$db->execute($sth,$bindvars);

Sybase與Microsoft SQL Server作法

首頁先建立一個預儲程式如下

create procedure testproc @in1 int, @in2 float, @in3 varchar(20) as
        insert into mytable values (@in1,@in2,@in3)

接下來直接用PEAR執行指定的預儲程式,並給予參數

$sth=$db->prepare("exec testproc");
$bindvars=array("in1" => 1,
                "in2" => 1.1,
                "in3" => "hello"})
$res=$db->execute($sth,$bindvars);

Postgresql的作法

首頁先建立一個預儲程式如下

create function testproc(int,float,varchar(20)) returns void as
begin
        insert into mytable values ($1,$2,$3);
        return;
end;

接下來直接用PEAR執行指定的預儲程式,並給予參數

$res=$db->prepare("select testproc(:in1,:in2,:in3)");
$bindvars=array("in1" => 1,
                "in2" => 1.1,
                "in3" => "hello"})
$res=$db->execute($res,$bindvars);

DB2的作法

首頁先建立一個預儲程式如下

create procedure testproc(in in1 int, in in2 double, in in3 varchar(20))
begin
        insert into mytable values (in1,in2,in3);
end;

接下來直接用PEAR執行指定的預儲程式,並給予參數

$sth=$db->prepare("call testproc(?,?,?)");
$bindvars=array("1" => 1,
                "2" => 1.1,
                "3" => "hello"})
$res=$db->execute($sth,$bindvars);

嗯…最後我就選用了MSSQL方法,不過結果竟然無效!!囧rz...。說真的我也不知道原因在哪,可是是PEAR::DB版本有更新吧,而且我又是外掛DB_odbtp去連MSSQL的,所以可能有些小問題,所以我最後改寫能跑的程式碼如下:

/********************************
 * 使用範例
 ********************************/
//指定執行的stored procedure與傳送的參數
$sth= $db->prepare("exec testproc @sDataType = ?,@beginNum = ?");

//建立參數
$params = array('Ver',0,0);

//檢查預儲程式是否有錯誤
if (PEAR::isError($sth)) {
    die('prepare error:'.$sth->getMessage());
}

//執行含有參數的預儲程式
$res = $db->execute($sth,$params);

//檢查執行是否有錯誤
if (PEAR::isError($res)) {
    if($res->getMessage() == 'DB Error: unknown error'){
		die('execute error:'.$res->userinfo);
	} else {
		die('execute error:'.$res->getMessage());
	}	
}

//讀取內容
while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
    echo $row['Version'] . "\n";
}

低溫烘培 發表在 痞客邦 PIXNET 留言(0) 人氣()