2011-12-20 8 views
2

私が$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スクリプトの匿名ブロックのように聞こえるのは、外部プロシージャと見なされます。

答えて

0

一時的なLOB(純粋なPl/SQLのようにPHPでも似ているかもしれません)と同様の困惑する問題が発生します。永続LOBSで正常に動作していたコードの一部は、一時LOBで動作しませんでした。いくつかの検索後、私はdocumentationにこのノートを見つけました:別のロケータはまた、それを指している間にユーザが一時LOBを変更する場合

、一時LOBのコピーが作成されます。変更が行われたロケータは、一時LOBの新しいコピーを指すようになりました。他のロケータは、変更が行われたロケータと同じデータを表示しません。 procedure p_clob_in_out(p_my_clob in out NOCOPY clob)

私はあなたの手順でNOCOPYを指定する場合は、同じ問題に実行する場合、見て好奇心だろう。また、手続き呼び出し後にロブに'ABC123... 'が含まれていることを確認できますか?

私の推論は次のとおりです。INパラメータが参照として渡されるため、INパラメータとして渡すとLOBが変更されます。 IN OUTパラメータは値によって渡されるため、プロシージャは一時LOBのコピーに適用されます(永続LOBはディープ・コピーされません)。

+0

それはそれと関係があるかもしれないと聞こえますが、手順でNOCOPYを指定すると、私はまだ同じ問題に遭遇します。 NOCOPYの有無にかかわらず、LOBには 'ABC123 ...'が含まれています。これを閉じるとエラーが発生します。 – Tim

+0

あなたの答えにあなたが提供したヒントのおかげで、何が起こっているのか分かりました。私はこのコメントのために長すぎるので私の発見と私の元の質問を編集しました。ありがとう! – Tim

+0

私はあなたの分析に同意します。私はコピーがあなたの割り当て行の予期せぬ結果であるかどうか疑問に思っています( 'p_my_clob:= 'ABC123 ...' || p_my_clob')。 DBMS_LOB.writeappend関数でテストできますか?つまり、dbms_lob.writeappend(p_my_clob、length( 'ABC123 ...')、 'ABC123 ...') ' –

関連する問題