|
ここにある情報はかなり古くなっており、正しくなくなっている可能性があります。掲載しているサンプルコードiなどは、最新のPHPでは動作しない、もしくは、別途設定・調整が必要になるかも知れません。情報を鵜呑みにせず、あなたの手を動かして、あなたの目で確認してください。
PHPマニュアルを見ると、Oracle 8関数の中にOCICancel関数があります。説明を見ると、「カーソルからの読み込みをキャンセルする」とあります。。。「何だろう?カーソルって、PL/SQLのカーソル?んなアホなぁ」と思っていましたが、試してみると「カーソルからの読み込みをキャンセルする」そのままでした。。。
今回の例は、
- ストアドパッケージでempテーブルの全件を取得するカーソルを定義し、それを返すプロシージャも用意
- それをPHPから呼びだし、カーソルを取得&Fetch
というもので、Fetch途中でOCICancel関数を実行した場合の結果がどうなるかを確認できます。PHPスクリプトの元ネタは、PHPマニュアルのOCINewCursor関数のページにあるサンプルです。
●ストアドパッケージ定義CREATE OR REPLACE PACKAGE info AS
TYPE curs IS REF CURSOR RETURN emp%ROWTYPE;
PROCEDURE getCursor(ret IN OUT curs);
END info;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY info AS
PROCEDURE getCursor(ret IN OUT curs) IS
BEGIN
OPEN ret FOR SELECT * FROM emp ORDER BY empno;
END getCursor;
END info;
/
SHOW ERRORS
●OCICancel.php
<?php
$conn = OCILogon("scott", "tiger", "orcl");
$curs = OCINewCursor($conn);
$stmt = OCIParse($conn, "begin info.getCursor(:data); end;");
OCIBindByName($stmt, "data", $curs, -1, OCI_B_CURSOR);
OCIExecute ($stmt);
OCIExecute ($curs);
$iter = 0;
while (@OCIFetchInto($curs,$data)) {
echo "<pre>";
var_dump($data);
echo "</pre>";
if ($iter++ >= 1) OCICancel($curs);
}
OCIFreeStatement($stmt);
OCIFreeCursor($curs);
OCILogoff($conn);
?>
実行すると、先頭の2レコードのみがFetch&表示されます。もちろん、Fetchの前にOCICancelすると、1レコードもFetch&表示されません。また、OCICancelした後にFetchしようとすると「ORA-01002: フェッチ順序が無効です。」となるので、エラーメッセージの表示を回避するために「@」を付けています。
|