sinkope is not kind of paradoxical existence

🎼 🎹 🏀 🌠 🚶 👣 📷 💻 🎨 🎮 📖 and more !

CLOBを返すストアドファンクションをPHP4で読み込む

OracleサーバがWindows2000、クライアントが Linux+PHP4 という異色の組み合わせ(笑)。ストアド組んでその戻りを受け取るのにチト手間取ってしまいました(汗
まぁ例えば次のようなファンクションを作ったとする。

create or replace package pros_clobtest is

function getclobtest(
  prCode     in varchar2
  )
 return clob
;
(略)

これをPHPで読み込もうとすると、次のようになりますわな。

$conn = ocilogon("foo","baa","HOGE");
$stSql = ociparse($conn,
 "select pros_clobtest.getclobtest(:codeval) retval from dual");

$bfCodeVal = "123";
$bfCLOB = OCINewDescriptor($conn, OCI_D_LOB);
OCIBindByName($stSql,"CODEVAL",&$bfCodeVal,-1);
OCIDefineByName($stSql,"RETVAL",&$bfRetVal,$bfCLOB);
OCIExecute($stSql);
while (OCIFetch($stSql)) {
    echo "result: " . $bfRetVal->load() . "\n";
}
OCIFreeStatement($stSql);

OCILogoff($conn);

最初、素で OCIDefineByName だけでやってたら "Object" とか返ってきて、「?」とかなってたんですが、OCINewDescriptor が必要だったとは。いや〜マニュアル読まないとダメですね(ぉぃ
ところが今度は日本語とかが文字化けしやがる。いやそれは別に CLOB だからってワケじゃなくて、フツーの項目でも化けやがる。んもー。SQL発行時に無理矢理 convert 関数とかで変換しようとしたけどダメ。そりゃそうか‥‥。
よくよく見直したら、実行ユーザの環境変数で NLS_LANG を設定してなかったのねん。

$ cat .bash_profile
(略)
export ORACLE_OWNER=oracle
export ORACLE_BASE=/home/oracle
export ORACLE_HOME=$ORACLE_BASE/product/8.0.5
export ORACLE_NLS33=$ORACLE_HOME/ocommon/nls/admin/data
export ORACLE_SID=ora8areis
export ORACLE_TERM=$TERM
export PATH=$PATH:$ORACLE_HOME/bin
export LD_LIBRARY_PATH=$ORACLE_HOME/lib
export ORACLE_DOC=$ORACLE_HOME/doc
export ULIMIT='ulimit'
export NLS_LANG=Japanese_Japan.JA16SJIS
umask 022
(略)
$ 

これでバッチリ。