0

変数を定義しました

define myStrings = "'abc','def'"

後でプロシージャブロック内で使用し、テーブルに変換する必要がありますvarchars

declare
    type varcharListType is table of varchar(200);
    myList varcharListType;

begin
    myList := varcharListType(&myStrings);
    .
    .
    .
end;
/

INプロシージャ ブロック内の作成クエリの句内で変数またはテーブルを使用しようとしています。

execute immediate 'create table tmp_foo '
               || 'as select * from bar '
               || 'where bar_val in (&myStrings) ';

the REPLACE関数も使ってみました

myNewStrings := replace(&myStrings, '''' , '''''');

しかし、定義されていないことにabc関連する例外が発生します。def

問題:

abc前後の引用符がエスケープされていないdefため、構文例外が発生します。myString"'abc','def'"は「宣言」するのではなく「定義」する必要があるため、後で置換されます。

質問:

変数をテーブル型の値としても、execute immediate ステートメントの文字列としても使用できるように、変数を「定義」することはできますか?

再現するには:

作成

create table bar (bar_id number not null, bar_val varchar2(20), 
  constraint bar_pk primary key (bar_id)
  enable 
);

入れる

insert into bar (bar_id, bar_val)
values (1, 'abc'),
       (2, 'def'),
       (3, 'ghi');

サンプル手順

set verify off;
set serveroutput on; 

define myStrings = "'abc','def'"

declare
    type varcharListType is table of varchar(20);
    myList varcharListType;

begin
    myList := varcharListType(&myStrings);

    execute immediate 'create table tmp_foo '
                   || 'as select * from bar '
                   || 'where bar_val in (&myStrings) ';

    for i in myList.FIRST..myList.LAST loop
        dbms_output.put_line('VALUE: ' || myList(i));
    end loop;
end;
/

set serveroutput off;
set verify on;
4

2 に答える 2

1

以下は、私が採用するアプローチです。ループ内での tablen の使用に注意してください。これは、DBMS_UTILITY.COMMA_TO_TABLE プロシージャがテーブルの最後に null 値を追加するためです。

これが役に立つことを願っています

declare

  myStrings varchar2(100) := '''abc'',''def''';
  myList dbms_utility.uncl_array;
  tablen number :=0;

begin

  DBMS_UTILITY.COMMA_TO_TABLE ( replace(myStrings, '''', ''),  tablen,  myList); 

  execute immediate 'create table tmp_foo '
               || 'as select * from bar '
               || 'where bar_val in (' ||myStrings||')';

  for i in myList.FIRST..tablen loop
    dbms_output.put_line('VALUE: ' || myList(i));
  end loop;
end;
/
于 2014-07-17T05:57:10.683 に答える