我正在使用存储过程使用游标选择记录。此过程将记录ID作为输入。
以下是代码:
create or replace
procedure GET_ITEM_DETAILS_ALL
(
cur_out out sys_refcursor,
PSTRING VARCHAR2 DEFAULT NULL
)
is
query_string VARCHAR2(1000);
Begin
query_string := 'Select IT.SL_NO from ITEM_DETAILS IT where IT.SL_NO in (:sl) order by IT.SL_NO';
OPEN cur_out FOR query_string USING PSTRING;
End;
为了调用/测试程序,我使用下面的代码:
VAR R REFCURSOR
EXEC GET_ITEM_DETAILS_ALL (:R, '4')
PRINT R
问题是当我传递一个整数时,例如' 4'或者' 2',程序返回数据,但是当我通过' 1,2'或者' 3,4',它显示错误。
答案 0 :(得分:2)
OPEN cur_out FOR Select IT.SL_NO from ITEM_DETAILS IT where IT.SL_NO in (SELECT REGEXP_SUBSTR(sl,'[^,]+', 1, LEVEL) FROM DUAL CONNECT BY REGEXP_SUBSTR(sl, '[^,]+', 1, LEVEL) IS NOT NULL ) order by IT.SL_NO
答案 1 :(得分:0)
您无法使用一个绑定变量将值列表传递给查询
传递带逗号分隔列表的字符串后,您的查询将变为
Select IT.SL_NO from ITEM_DETAILS IT where IT.SL_NO in ('1,2') order by IT.SL_NO
这是不正确的
您应该手动将输入字符串转换为查询中的值列表。
答案 2 :(得分:0)
问题是PSTRING是单个变量而不是数组。所以你的陈述实际上等同于
.... where IT.SL_NO = PSTRING
这就是为什么当你通过4
时它会起作用而在你通过1,2
时失败的原因。
使用动态SQL没有任何价值(我们可以在不使用字符串的情况下打开引用游标)。但是,利用动态SQL是解决问题的一种方法:
query_string := 'Select IT.SL_NO from ITEM_DETAILS IT where IT.SL_NO in ('
||PSTRING||
') order by IT.SL_NO';
OPEN cur_out FOR query_string;
或者,您可以使用字符串标记生成器将字符串转换为标记。遗憾的是,Oracle没有内置的标准,但有不同版本的数据库有各种变通方法。阿德里安·比林顿有a good round-up on his site。使用这些方法之一允许您放弃动态SQL:
OPEN cur_out FOR select IT.SL_NO from ITEM_DETAILS IT
where IT.SL_NO in ( select * from table ( your_string_tokenizer( PSTRING ) ) )
order by IT.SL_NO;
答案 3 :(得分:0)
解决方案如下:
create or replace procedure GETITEM_DETAILS_ALL
(
cur_out out sys_refcursor,
PSTRING VARCHAR2 DEFAULT NULL
)
is
query_string VARCHAR2(1000);
Begin
query_string := 'Select IT.SL_NO from ITEM_DETAILS IT where IT.SL_NO in (' || PSTRING || ') order by IT.SL_NO';
OPEN cur_out FOR query_string;
End;