|
ここにある情報はかなり古くなっており、正しくなくなっている可能性があります。掲載しているサンプルコードiなどは、最新のPHPでは動作しない、もしくは、別途設定・調整が必要になるかも知れません。情報を鵜呑みにせず、あなたの手を動かして、あなたの目で確認してください。
[2004/11/25] 今までに動作確認できた環境は、PHP4.2.0/4.2.1/4.2.2+Oracle8.1.6i/8.1.7i Enterprise Edition、PHP4.3.0pre2/4.2.2+Oracle8.1.5i、PHP4.3.9+Oracle9.2.0i Standard Editionという環境です。その他情報をお持ちの方は是非ご一報下さい。
php-usersにも流しましたが、ストアドプロシージャ・ファンクションから配列(VARRAY型)を受け取るには、PHP4.0.6から追加されたOCINewCollection関数を使います。例として、以下のようなVARRAY型のTYPEを使って、emp表のENAMEを返すプロシージャ・ファンクションを考えてみます。
●TYPEの定義CREATE OR REPLACE TYPE test_arr AS VARRAY(100) OF VARCHAR2(10);
/
SHOW ERRORS
まずは、php-usersに流したファンクションの場合。。。
●ストアドファンクションの定義CREATE OR REPLACE FUNCTION getUsers(
nm IN VARCHAR2 := ''
) RETURN test_arr
IS
CURSOR c1 IS
SELECT ename FROM emp
WHERE ename LIKE nm||'%';
cnt INTEGER := 0;
ret test_arr := test_arr();
BEGIN
FOR csr IN c1 LOOP
cnt := cnt + 1;
ret.EXTEND(1);
ret(cnt) := csr.ename;
END LOOP;
RETURN ret;
EXCEPTION
WHEN OTHERS THEN
RETURN test_arr();
END;
/
SHOW ERRORS
これに対するPHPスクリプトは、以下のようになります。
●PHPスクリプト(ストアドファンクションの場合)
<?php
$nm = "";
$conn = OCILogon("scott","tiger", "orcl");
$coll = OCINewCollection($conn, "TEST_ARR");
$stmt = OCIParse($conn, "begin :ret := getUsers(:nm); end; ");
OCIBindByName($stmt, ':RET', $coll, -1, OCI_B_SQLT_NTY);
OCIBindByName($stmt, ':NM', $nm, -1);
OCIExecute($stmt);
for ($i = 0; $i < $coll->size(); $i++) {
printf("%d => %s<br />", $i, $coll->getElem($i));
}
OCIFreeCollection($coll);
OCIFreeStatement($stmt);
OCILogOff($conn);
?>
次に、プロシージャの場合。。。
●ストアドプロシージャの定義CREATE OR REPLACE PROCEDURE pgetUsers(
nm IN VARCHAR2 := '',
ret OUT test_arr
)
IS
CURSOR c1 IS
SELECT ename FROM emp
WHERE ename LIKE nm||'%';
cnt INTEGER := 0;
BEGIN
ret := test_arr();
FOR csr IN c1 LOOP
cnt := cnt + 1;
ret.EXTEND(1);
ret(cnt) := csr.ename;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
ret := test_arr();
END;
/
SHOW ERRORS
これに対するPHPスクリプトの差分は、以下のようになります。ファンクションとの違いは、実行する無名プロシージャだけです。
●PHPスクリプト(ストアドプロシージャの場合)
<?php
:
$stmt = OCIParse($conn, "begin pgetUsers(:nm, :ret); end; ");
:
?>
初め、PHPマニュアルにもあるOCICollSize関数やOCICollGetElem関数を使ってみたところ、何も帰ってこなかったのでまだダメかと思いましたが、OCINewCollection関数の戻り値がObject(gettype関数で確認)でしたので、「ひょっとしてメソッドなら。。。」ということで試してみました。関数でうまくいった方がいらっしゃいましたら、情報をお願いします(^-^;
|