45

PL/SQLの動的SQL文でバインド変数をどこで使用できるかについて質問があります。

たとえば、これが有効であることはわかっています。

CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2) 
RETURN NUMBER
IS
  v_query_str VARCHAR2(1000);
  v_num_of_employees NUMBER;
BEGIN
  v_query_str := 'SELECT COUNT(*) FROM emp_' 
                 || p_loc
                 || ' WHERE job = :bind_job';                           
  EXECUTE IMMEDIATE v_query_str
    INTO v_num_of_employees
    USING p_job;
  RETURN v_num_of_employees;
END;
/

このような選択ステートメントでバインド変数を使用できるかどうか疑問に思っていました

CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2) 
RETURN NUMBER
IS
  v_query_str VARCHAR2(1000);
  v_num_of_employees NUMBER;
BEGIN
  v_query_str := 'SELECT COUNT(*) INTO :into_bind FROM emp_' 
                 || p_loc
                 || ' WHERE job = :bind_job';                           
  EXECUTE IMMEDIATE v_query_str
    USING out v_num_of_employees, p_job;
  RETURN v_num_of_employees;
END;
/

注: 動的文字列として SELECT INTO ステートメントを使用し、INTO 句でバインド変数を使用しました。

私は現在旅行中で、数日間自宅に戻って自分のコンピューターにアクセスできませんが、これは私を少し悩ませています. PL/SQL リファレンスを読んでみましたが、このような選択の例はありません。

ありがとう

4

5 に答える 5

30

私の意見では、動的PL/SQLブロックはややあいまいです。非常に柔軟性がありますが、調整もデバッグも難しく、何が起きているのかを理解するのも困難です。私の投票はあなたの最初の選択肢に行きます、

EXECUTE IMMEDIATE v_query_str INTO v_num_of_employees USING p_job;

どちらもバインド変数を使用しますが、最初に、私にとっては、@jonearlesオプションよりも再利用可能で調整可能です。

于 2011-10-19T07:27:01.677 に答える
28

いいえ、そのようにバインド変数を使用することはできません。2 番目の例:into_bindでは、 variable の値のv_query_str単なるプレースホルダーv_num_of_employeesです。select into ステートメントは次のようになります。

SELECT COUNT(*) INTO  FROM emp_...

の値が にあるv_num_of_employeesためnullですEXECUTE IMMEDIATE

最初の例は、戻り値を変数にバインドする正しい方法を示しています。

編集

元の投稿者は、回答で参照している2番目のコードブロックを編集して、デフォルトモードの代わりにOUTパラメーターモードを使用しました。この変更により、両方の例が機能的に同等になります。v_num_of_employeesIN

于 2011-10-19T04:35:48.970 に答える
19

select ステートメントを動的 PL/SQL ブロックに入れます。

CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2) 
RETURN NUMBER
IS
  v_query_str VARCHAR2(1000);
  v_num_of_employees NUMBER;
BEGIN
  v_query_str := 'begin SELECT COUNT(*) INTO :into_bind FROM emp_' 
                 || p_loc
                 || ' WHERE job = :bind_job; end;';
  EXECUTE IMMEDIATE v_query_str
    USING out v_num_of_employees, p_job;
  RETURN v_num_of_employees;
END;
/
于 2011-10-19T04:49:44.970 に答える
0

バインド変数は、"in" 句を使用して Oracle SQL クエリで使用できます。

10g で動作します。他のバージョンについてはわかりません。

バインド変数は、最大 4000 文字の varchar です。

例: コンマ区切りの値のリストを含むバインド変数。

:bindvar = 1,2,3,4,5

select * from mytable
  where myfield in
    (
      SELECT regexp_substr(:bindvar,'[^,]+', 1, level) items
      FROM dual
      CONNECT BY regexp_substr(:bindvar, '[^,]+', 1, level) is not null
    );

(ここに投稿したのと同じ情報: How do you specify IN clause in a dynamic query using a variable? )

于 2016-06-11T17:38:42.133 に答える
-2

Select Into 機能は PL/SQL ブロックに対してのみ機能します。Execute immediately を使用すると、oracle は v_query_str を SQL クエリ文字列として解釈するため、into .will get キーワードが見つからない例外を使用できません。例 2 では、begin end を使用しています。したがって、それはpl/sqlブロックになり、合法になりました。

于 2016-12-27T11:34:40.333 に答える