動的SQLは、ステートメントが実行されようとするまで知られていないSQLステートメントを実行する能力を提供する技術である。
この時点まで、SPLプログラムで説明されているSQLステートメントは静的SQLでした。プログラム自体が実行を開始する前に、完全なステートメント (変数を除く) を認識し、プログラムにコード化する必要があります。 したがって、動的SQLを使用することによって、実行されるSQLは、プログラムの実行中に変化し得る。
さらに、動的SQLは、CREATE TABLEなどのデータ定義ステートメントをSPLプログラム内から実行できる唯一のメソッドです。
ただし、動的SQLの実行時のパフォーマンスは静的SQLよりも遅くなります。
EXECUTE IMMEDIATEステートメントは、SQLステートメントを動的に実行するために使用されます。
EXECUTE IMMEDIATE 'sqL_expression;'
[INTO { variable [, ...] | record } ]
[USING式 [, ...] ] sql_expressionは、動的に実行されるSQL文を含む文字列式です。 変数は、通常、SELECTステートメントから結果セットの出力を受け取ります。 このステートメントは、sql_expressionでSQLステートメントを実行した結果として作成されます。 変数の数、順序、および型は、数、順序と一致し、結果セットのフィールドと型互換性がある必要があります。 あるいは、レコードのフィールドが番号、順序と一致し、結果セットとタイプ互換性がある限り、レコードを指定できます。 INTO句を使用する場合、結果セットで正確に1行を返す必要があります。 そうでない場合、例外が発生する。 USING句を使用すると、式の値がプレースホルダーに渡されます。 プレースホルダーは、sql_expressionのSQL文に埋め込まれて表示され、変数を使用できます。 プレースホルダーは、コロン (:) プレフィックス- :nameを持つ識別子で示されます。 評価される式の数値、順序、および結果のデータ型は、数値、順序と一致し、sql_expressionのプレースホルダーと型互換性がある必要があります。 プレースホルダーはSPLプログラムのどこにも宣言されず、sql_expressionにのみ表示されることに注意してください。
次の例は、基本的な動的SQLステートメントを文字列リテラルとして示しています。
DECLARE
v_sql VARCHAR2(50);
開始
EXECUTE IMMEDIATE 'CREATE TABLEジョブ (jobno NUMBER (3),'| |
'jname VARCHAR2(9))';
v_sql := 'INSERT INTO job VALUES (100, ''ANALYST'')';
即時実行v_sql;
v_sql := 'INSERT INTO job VALUES (200, ''CLERK'')';
即時実行v_sql;
エンド; 次の例は、SQL文字列のプレースホルダーに値を渡すためのUSING句を示しています。
DECLARE
v_sql VARCHAR2(50) := 'INSERT INTO job VALUES '| |
'(:p_jobno, :p_jname)';
v_jobnoジョブ。jobno % TYPE;
v_jname job.jname % TYPE;
開始
V_jobno: = 300;
v_jname := 'MANAGER ';
実行即時v_sql使用v_jobno、v_jname;
v_jobno := 400;
v_jname := 'SALESMAN';
実行即時v_sql使用v_jobno、v_jname;
v_jobno := 500;
v_jname := 'PRESIDENT';
実行即時v_sql使用v_jobno、v_jname;
エンド; 次の例は、INTO句とUSING句の両方を示しています。 SELECTステートメントを最後に実行すると、個々の変数ではなくレコードに結果が返されます。
DECLARE
v_sql VARCHAR2(60);
v_jobnoジョブ。jobno % TYPE;
v_jname job.jname % TYPE;
r_jobジョブ % ROWTYPE;
開始
DBMS_OUTPUT.PUT_LINE('JOBNO JNAME');
DBMS_OUTPUT.PUT_LINE('----- -------');
v_sql := 'SELECT jobno, jname FROM job WHERE jobno = :p_jobno ';
実行即時v_sqlにv_jobno、v_jname使用100;
DBMS_OUTPUT.PUT_LINE(v_jobno | | '| | v_jname);
実行即時v_sqlにv_jobno、v_jname使用200;
DBMS_OUTPUT.PUT_LINE(v_jobno | | '| | v_jname);
実行即時v_sqlにv_jobno、v_jname使用300;
DBMS_OUTPUT.PUT_LINE(v_jobno | | '| | v_jname);
実行即時v_sqlにv_jobno、v_jname使用400;
DBMS_OUTPUT.PUT_LINE(v_jobno | | '| | v_jname);
500を使用してr_jobに即時実行します。
DBMS_OUTPUT.PUT_LINE(r_job.jobno | | '| | r_job.jname);
エンド; 次のコードは、前の匿名ブロックからの出力です。
JOBNO JNAME
----- -------
100アナリスト
200 CLERK
300マネージャー
400 SALESMAN
500大統領 BULK COLLECT句を使用して、EXECUTE IMMEDIATEステートメントの結果セットを名前付きコレクションに組み立てることができます。