私が$lob->writeTemporary()
を使用して以来、私はLOBとOCI8 PHP拡張機能に関する文書から、$lob->close()
を以下のコードに呼び出すべきであると思われます。 $lob->close()
は、INパラメータを受け入れるストアドプロシージャにLOBを渡しているときにうまく動作しますが、IN OUTパラメータを受け入れるストアドプロシージャにLOBを渡しても機能しません。IN OUTパラメータでOCI-Lob-> closeが機能しないのはなぜですか?
明らかに私はIN OUTパラメータのために$lob->close()
への呼び出しを外すことができますが、なぜ私が必要なのか不思議です。誰かが、以下のエラーを引き起こす原因となる以下のコードで何が起きているのかを教えてください。どんな洞察も大変ありがとうございます。
OCI-LOBが::近い()[OCI-lob.close]:ORA-22289:未開封ファイルに%sの操作を行うことができないか、LOB
$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'sの答えに、私は、これは、私のPHPコードでは...何が起こっているかだと思います変数は渡される一時LOBです。一時LOBはプロシージャによって変更され、プロシージャによってそのコピーが作成されます。コピーはその後渡され、$lob
変数に置き換えられます。 writeTemporary
メソッドはLOBのコピーでは一度も呼び出されませんでしたので、$lob->close()
を呼び出すと失敗します。最初に作成された元のLOB($lob->close()
を呼び出すことができる)は、PHPスクリプトからアクセスできなくなりました。
"NOCOPYの制限事項"のthis pageに "サブプログラムがデータベースリンクまたは外部プロシージャとして呼び出された場合、NOCOPYが無視されることを示しているため、NOCOPYヒントがここでは適用されない可能性があります。 this pageによると、ストアドプロシージャを呼び出すPHPスクリプトの匿名ブロックのように聞こえるのは、外部プロシージャと見なされます。
それはそれと関係があるかもしれないと聞こえますが、手順でNOCOPYを指定すると、私はまだ同じ問題に遭遇します。 NOCOPYの有無にかかわらず、LOBには 'ABC123 ...'が含まれています。これを閉じるとエラーが発生します。 – Tim
あなたの答えにあなたが提供したヒントのおかげで、何が起こっているのか分かりました。私はこのコメントのために長すぎるので私の発見と私の元の質問を編集しました。ありがとう! – Tim
私はあなたの分析に同意します。私はコピーがあなたの割り当て行の予期せぬ結果であるかどうか疑問に思っています( 'p_my_clob:= 'ABC123 ...' || p_my_clob')。 DBMS_LOB.writeappend関数でテストできますか?つまり、dbms_lob.writeappend(p_my_clob、length( 'ABC123 ...')、 'ABC123 ...') ' –