我在PL / SQL块中设置了一个绑定变量,我试图在另一个查询的IN表达式中使用它。像这样:
variable x varchar2(255)
declare
x varchar2(100);
begin
for r in (select id from other_table where abc in ('&val1','&val2','&val3') ) loop
x := x||''''||r.id||''',';
end loop;
--get rid of the trailing ','
x:= substr(x,1,length(x)-1);
select x into :bind_var from dual;
end;
/
print :bind_var;
select *
from some_table
where id in (:bind_var);
我在尝试使用“IN”列表中的绑定变量的查询中收到错误(ORA-01722:无效数字)。
print statement yiels '123','345'
这就是我的期望。
是否可以像这样使用绑定变量,还是应该尝试不同的方法?
(使用Oracle 10g)
澄清:
这是一种和解的事情。我想跑
select *
from some_table
where id in (select id from other_table where abc in ('&val1','&val2','&val3'))
在脚本的主要部分(此处未图示)之前删除了一大堆记录。我想在之后再次运行它以验证some_table
中的记录是否尚未删除。但是,other_table
DOES中的数据会被此过程删除,因此我不能仅仅引用other_table
中的数据,因为那里没有任何内容。我需要一种方法来保留other_table.id
值,以便我可以在之后验证父记录。
答案 0 :(得分:6)
我会将other_table.id
存储在PL / SQL表中,然后在查询中引用该表:
type t_id_table is table OF other_table.id%type index by binary_integer;
v_table t_id_table;
-- fill the table
select id
bulk collect into v_table
from other_table
where abc in ('&val1','&val2','&val3');
-- then at a later stage...
select *
from some_table st
, table(cast(v_table AS t_id_table)) idt
where st.id = idt.id;
答案 1 :(得分:1)
您不能在一个绑定变量中使用逗号分隔值。
你可以说:
select * from some_table where id in (:bind_var1, :bind_var2)
虽然
你最好使用类似的东西:
select * from some_table where id in ("select blah blah blah...");
答案 2 :(得分:1)
我会为此目的使用全局临时表
create global temporary table gtt_ids( id number ) ;
然后
...
for r in (select id from other_table where ... ) loop
insert into gtt_ids(id) values (r.id) ;
end loop;
...
并在最后
select *
from some_table
where id in (select id from gtt_ids);
答案 3 :(得分:0)
好的,我有一种丑陋的解决方案也使用替代变量...
col idList NEW_VALUE v_id_list /* This is NEW! */
variable x varchar2(255)
declare
x varchar2(100);
begin
for r in (select id from other_table where abc in ('&val1','&val2','&val3') ) loop
x := x||''''||r.id||''',';
end loop;
--get rid of the trailing ','
x:= substr(x,1,length(x)-1);
select x into :bind_var from dual;
end;
/
print :bind_var;
select :x idList from dual; /* This is NEW! */
select *
from some_table
where id in (&idList); /* This is CHANGED! */
它有效,但如果它更优雅,我会接受别人的回答。
答案 4 :(得分:0)
将循环更改为使用listagg(遗憾的是,这只适用于11gr2)。
但是对于列表中的变量,我使用regular expression来完成目标(但是前10g你可以使用substr来做同样的事情)这是从链接的asktom问题解除的。
variable bind_var varchar2(255)
variable dataSeperationChar varchar2(255)
declare
x varchar2(100);
begin
select listagg(id,',') within group(order by id) idList
into x
from(select level id
from dual
connect by level < 100 )
where id in (&val1,&val2,&val3) ;
select x into :bind_var from dual;
:dataSeperationChar := ',';
end;
/
print :bind_var;
/
select *
from (
select level id2
from dual
connect by level < 100
)
where id2 in(
select -- transform the comma seperated string into a result set
regexp_substr(:dataSeperationChar||:bind_var||','
, '[^'||:dataSeperationChar||']+'
,1
,level) as parsed_value
from dual
connect by level <= length(regexp_replace(:bind_var, '([^'||:dataSeperationChar||'])', '')) + 1
)
;
/*
values of 1,5, and 25
BIND_VAR
------
1,5,25
ID2
----------------------
1
5
25
*/
修改强>
哎呀只是注意到你标记了10g,唯一要做的就是不要使用我在开始时做的listagg