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;
/