LOBとOCI8PHP拡張機能に関して読んだドキュメントから、$lob->close()
を使用したので、以下のコードを呼び出す必要があるよう$lob->writeTemporary()
です。$lob->close()
INパラメーターを受け入れるストアード・プロシージャーにLOBを渡す場合は正常に機能しますが、IN OUTパラメーターを受け入れるストアード・プロシージャーにLOBを渡す場合は機能しません。
明らかに$lob->close()
、IN OUTパラメーターの呼び出しを省略できますが、なぜそうする必要があるのか知りたいです。誰かが次のエラーを生成する原因となる以下のコードで何が起こっているのか説明してもらえますか?どんな洞察も大歓迎です。
OCI-Lob :: close()[oci-lob.close]:ORA-22289:開いていないファイルまたはLOBに対して%s操作を実行できません
$my_clob = 'Lorem ipsum dolor sit amet...';
$connection = oci_connect('user', 'pass', 'connection string');
$statement = oci_parse($connection, 'begin p_clob_in_out(:p_my_clob); end;');
$lob = oci_new_descriptor($connection, OCI_D_LOB);
$lob->writeTemporary($my_clob, OCI_TEMP_CLOB);
oci_bind_by_name($statement, ':p_my_clob', $lob, -1, OCI_B_CLOB);
oci_execute($statement, OCI_DEFAULT);
if (is_object($lob))
{
$data = $lob->load();
$lob->close();
$lob->free();
}
echo $data;
手順は次のp_clob_in_out
ようになります。
procedure p_clob_in_out(
p_my_clob in out clob
)
is
begin
p_my_clob := 'ABC123... ' || p_my_clob;
end p_clob_in_out;
Vincent Malgratの回答のおかげでさらに読むと、これが起こっていると思います...私のPHPコードでは、$lob
変数は渡される一時LOBです。その一時LOBは、プロシージャによって変更され、そのコピーが作成されます。 。次に、コピーが渡され、$lob
変数が置き換えられます。このwriteTemporary
メソッドはLOBのコピーで呼び出されなかったため、呼び出す$lob->close()
と失敗します。最初に作成された(私が呼び出すことができる$lob->close()
)元のLOBには、PHPスクリプトからアクセスできなくなりました。
このページの「NOCOPYの制限」では、「サブプログラムがデータベースリンクを介して、または外部プロシージャとして呼び出された場合」、NOCOPYは無視されると記載されているため、NOCOPYヒントはここでは当てはまらないと思います。このページによると、ストアドプロシージャを呼び出しているPHPスクリプトの匿名ブロックは、外部プロシージャと見なされるようです。