可変数のバインドを使用したOracle EXECUTE IMMEDIATEは可能ですか?
-
06-07-2019 - |
質問
実行前にSQLで使用されるバインド変数の正確な数がわからない場合、Oracleで動的SQL実行を使用する必要があります。
何らかの方法で EXECUTE IMMEDIATE
の呼び出しで可変数のバインド変数を使用する方法はありますか?
具体的には、不明なSQLに one パラメーターを渡す必要がありますが、そこで使用される頻度はわかりません。
次のようなものを試しました
EXECUTE IMMEDIATE 'SELECT SYSDATE FROM DUAL WHERE :var = :var' USING 1;
ただし、 ORA-01008:すべての変数がバインドされているわけではありません。
解決
EXECUTE IMMEDIATE
でこれを行うことはできません。ただし、Oracleの DBMS_SQL
パッケージを使用してこれを行うことができます。 データベースアプリケーション開発者ガイドには使い慣れている EXECUTE IMMEDIATE
と dbms_sql
メソッドの比較。 このページにはドキュメント DBMS_SQL
。ただし、いくつかの例(上記にリンク)が用意されています(例1は、任意の数のバインド変数を持つステートメントを実行する単純なケースです)。 DBMS_SQL
はコーディングの観点からはかなり面倒ですが、考えられることなら何でもできます。
SQLで発生するバインド変数の複数のインスタンスが許可されます。ただし、 DBMS_SQL.BIND_VARIABLE
に渡すには、バインド変数として使用されている名前(例では:var)を知る必要があります。
他のヒント
WITH
ステートメントを使用して、この問題を回避することもできます。一般に DBMS_SQL
を使用する方が良いですが、これはより簡単な方法です:
BEGIN
EXECUTE IMMEDIATE 'WITH var AS (SELECT :var FROM dual) SELECT SYSDATE FROM DUAL WHERE (SELECT * FROM var) = (SELECT * FROM var)' USING 1;
END;
Steve Brobergが説明したように dbms_sql
を使用できますが、結果のカーソルは多くのクライアントで消費(読み取り)できません。 Oracle 11は変換関数を追加しました( dbms_sql .to_refcursor
)。これにより、 dbms_sql
カーソルをrefカーソルに変換できますが、何らかの理由で、この変換されたrefカーソルを.Netアプリケーションで使用することはできません。 .netでは通常の参照カーソルを使用できますが、以前は dbms_sql
カーソルであった参照カーソルは使用できません。
では、どの種類のクライアントがこのカーソルを使用しますか?