Stored procedures 定义与声明-转义引号

Stored procedures 定义与声明-转义引号,stored-procedures,plsql,oracle10g,execute-immediate,Stored Procedures,Plsql,Oracle10g,Execute Immediate,我定义了一个变量 define myStrings = "'abc','def'" 稍后我需要在过程块中使用它,并将其转换为varchars declare type varcharListType is table of varchar(200); myList varcharListType; begin myList := varcharListType(&myStrings); . . . end; / 我试图在过程块内的cr

我定义了一个变量

define myStrings = "'abc','def'"
稍后我需要在过程块中使用它,并将其转换为
varchars

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

begin
    myList := varcharListType(&myStrings);
    .
    .
    .
end;
/
我试图在过程块内的create查询中使用
IN
子句中的变量或表

execute immediate 'create table tmp_foo '
               || 'as select * from bar '
               || 'where bar_val in (&myStrings) ';
我也尝试过使用
REPLACE
功能

myNewStrings := replace(&myStrings, '''' , '''''');
但是我得到了一个与未定义的
abc
def
相关的异常

问题:

我得到一个语法异常,因为
myString
abc
def
的引号没有转义。值
“'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;

下面是我将采取的方法,注意循环中使用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;
/

感谢@ShaunPeterson为解决此问题提供了灵感。虽然它直接解决了问题,但它提供了正确的方法,因此所有的
+1
都应该交给他

他的回答没有达到的地方是他“声明”了myStrings,而不是“定义”它

declare
  myStrings varchar2(100) := '''abc'',''def''';
不是

这就是问题的症结所在。在PL/SQL中,为过程块“声明”的变量(如下面的
myStringsVar
)不会像“定义”的变量那样被替换。根据OP的要求,“mystring”首先被“定义”,然后被转换为在过程块中使用

因此,生成的解决方案如下所示:

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

declare

  myStringsVar varchar2(100) := '&myStrings';
  myList dbms_utility.uncl_array;
  tablen number :=0;

begin

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

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

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

引用的
executeimmediate
字符串可能重复。有关更多详细信息,请参阅副本。或者您可以将单引号加倍,如
define myStrings=“'abc”“,'def”“”
。分享并享受。可能重复感谢您的建议,但是似乎
replace
函数将mystring视为参数。即使在引用引用引用
“&myStrings”
“&myStrings”
时,仍会引发语法异常。您是否有机会运行该示例?
define myStrings = "''abc'',''def''"

declare

  myStringsVar varchar2(100) := '&myStrings';
  myList dbms_utility.uncl_array;
  tablen number :=0;

begin

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

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

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