2011-07-15 8 views
5

現在、.NETコードはODP.NETを使用して、多くの表のさまざまな行を操作するストアド・プロシージャを何度も呼び出します。 .NETコードには、変更する行の配列があります。コールごとに1つのパラメータだけが変更され、.NETからPL/SQLに配列を渡して、複数の行を操作する必要があります(行数が変更されます)。PL/SQLでVARRAYを使用してSQL 'IN'(または 'ANY')演算子を使用する方法

私が使用して.NETからPL/SQLに配列を合格しました:私はnumber_arrがVARRAYと呼ばれていると信じて

type number_arr is table of number(10) index by pls_integer; 
PROCEDURE "BLAH" (foo IN number_arr); 

注意を、私はそれについて肯定的ではないよ、と誰かが望んでいる場合私を修正するために、(コメントとして)してください、しかし、これは私の混乱に貢献している可能性があります。 fooが配列ではなかったとき

UPDATE t SET a = b WHERE a = foo; 

はしかし、今、PL/SQLには、私が見えるように使用される多くの更新ステートメントを持っています。

UPDATE t SET a = b WHERE a IN (foo); 

しかし、この構文は機能していないようです。そして、私はVARRAYと 'IN'(または 'ANY'など)の使用を組み合わせたOracleの例を見つけることができませんでした。 SQL Serverでこれを行う方法についていくつかの回答がありましたが、Oracleに変換する方法がわかりません。

もちろん、これを行うために.NETからストアドプロシージャに配列を取得する他の方法がある場合は、それも私の質問に答えます。私はINで効率を得るために探しているので、PL/SQLで配列を繰り返し処理するもの(UPDATE文を別々に呼び出す)はおそらく役に立ちません。

答えて

8

使用しているアレイは、associative arrayで、VARRAYではありません。 VARRAYおよびNESTED TABLEはSQLでは使用できますが、連想配列では使用できません。あなたが最初の場所でPL/SQLでこれをやろうとしているので、あなたは(連想配列で動作します)バルクバインドを使用することができます:あなたは可変長配列のようにnumber_arr作成した場合

PROCEDURE BLAH (foo IN number_arr) is 
i number; 
begin 
    forall i in foo.first .. foo.last 
    UPDATE t SET a = b WHERE a = foo(i); 
end blah; 

、この場合には、種類がないあなたのパッケージに、データベースに定義する必要があり

create type number_arr as varray(10) of number; 

CREATE PROCEDURE BLAH (foo IN number_arr) is 
begin 
    UPDATE t SET a = b WHERE a in (select * from table(foo)); 
end blah; 

注:代わりに連想配列のデータベースは、あなたの代わりに表関数を使用することができます。また、この方法は必ずしもforallを使用するより高速であるとは限りません。

+0

最後のコードスニペットでは、 'table(foo)'は 'table(cast(foo as number_arr))'である必要があります。しかし全体的に、良い答え。 –

+0

@Dave:それはしばしばそのように行われますが、必ずしもそうする必要はありません。 – Allan

+0

あなたは正しいです!私は過去のある時点でCASTが必要だったと思うが、10.2.0.4のテストではそれは今ではないことを示している。 –

関連する問題