PL/SQLの動的SQLを使用すると、実行時にSQLステートメントを構築および実行できます。これは、入力パラメーターまたはコンパイル時に知られていない他のランタイム条件に基づいてクエリを構築する必要がある場合に非常に便利です。主要なメカニズムはEXECUTE IMMEDIATE
です。このステートメントは、SQLステートメントを入力として含む文字列を取得し、直接実行します。
これが基本的な例です。
<code class="sql">DECLARE v_sql VARCHAR2(200); v_emp_id NUMBER := 100; v_emp_name VARCHAR2(50); BEGIN v_sql := 'SELECT first_name FROM employees WHERE employee_id = ' || v_emp_id; EXECUTE IMMEDIATE v_sql INTO v_emp_name; DBMS_OUTPUT.PUT_LINE('Employee Name: ' || v_emp_name); END; /</code>
このコードスニペットは、 v_emp_id
の値に基づいてSELECT
ステートメントを動的に構築します。 EXECUTE IMMEDIATE
ステートメントは、この動的に生成されたクエリを実行し、結果はv_emp_name
に保存されます。複数の行を返すクエリの場合、ループ内でOPEN FOR
、 FETCH
、およびCLOSE
声明を開いたカーソルを使用します。例えば:
<code class="sql">DECLARE v_sql VARCHAR2(200); v_dept_id NUMBER := 10; type emp_rec is record (first_name VARCHAR2(50), last_name VARCHAR2(50)); type emp_tab is table of emp_rec index by binary_integer; emp_data emp_tab; i NUMBER; BEGIN v_sql := 'SELECT first_name, last_name FROM employees WHERE department_id = ' || v_dept_id; OPEN emp_cursor FOR v_sql; LOOP FETCH emp_cursor INTO emp_data(i); EXIT WHEN emp_cursor%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Employee Name: ' || emp_data(i).first_name || ' ' || emp_data(i).last_name); i := i 1; END LOOP; CLOSE emp_cursor; END; /</code>
これは、動的に生成されたクエリによって返される複数の行を処理する方法を示しています。 EXCEPTION
ブロックを使用して、常に潜在的な例外を処理することを忘れないでください。
動的なSQLを使用した最大のセキュリティリスクは、 SQLインジェクションです。ユーザーがサプリした入力が適切な消毒なしにSQLステートメントに直接連結されている場合、攻撃者は悪意のあるコードを注入し、アクセスできないデータを読み取り、変更、または削除できる可能性があります。
緩和戦略:
EXECUTE IMMEDIATE
ステートメントは、わずかに異なる構文を使用してバインド変数をサポートします。<code class="sql">DECLARE v_emp_id NUMBER := :emp_id; -- Bind variable v_emp_name VARCHAR2(50); BEGIN EXECUTE IMMEDIATE 'SELECT first_name FROM employees WHERE employee_id = :emp_id' INTO v_emp_name USING v_emp_id; -- Binding the value DBMS_OUTPUT.PUT_LINE('Employee Name: ' || v_emp_name); END; /</code>
動的SQLのパフォーマンスは、いくつかの要因によって影響を受ける可能性があります。最適化する方法は次のとおりです。
INTO
にEXECUTE IMMEDIATE
します。カーソルはオーバーヘッドを紹介します。上記のポイントを組み合わせて、ベストプラクティスの要約を次に示します。
以上がPL/SQLで動的SQLを使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。