目前,我在下面的语句我的PL / SQL代码:
-- vList looks like '1,2,3,4'
vStatement := 'SELECT NAME FROM T_USER WHERE ID IN ( ' || vList || ' ) ';
Execute Immediate vStatement BULK COLLECT INTO tNames;
我认为,串联查询,如果不好的做法,所以我想使这个查询,而无需使用蜇伤。 什么是重写这个方法是什么?
PS也许这里的人能够指出为什么查询的串联是不好的,因为我没有足够的理由证明,这种风格是坏的。
我的猜测是,你采取了一些步骤之前获得VLIST的ID为分隔字符串(你不说VLIST如何填充)。 为什么不继续作为一个查询?
begin
...
select name
bulk collect into tNames
from t_user
where id in (select id from some_table where ...);
...
上下文时多次运行可能是痛苦的,但对我来说最糟糕的是,你是盲目地接受参数输入是数字的列表,当它可以是任何东西真的开关。 这可能(天真)是“1,2,X”,你会得到一个运行时错误“无效号码”。 更糟的是,它可能是一个SQL注入攻击。 它一般是不好的做法(动态SQL的确有它的地方),但肯定你不是如何使用它。
尝试是这样的:
create or replace type t_num_tab as table of number;
create or replace procedure test_proc(i_list in t_num_tab) as
type t_name_tab is table of varchar2(100);
l_names t_name_tab;
begin
-- get names
select name
bulk collect into l_names
from user_table
where id in (select * from table(i_list));
-- do something with l_names
dbms_output.put_line('Name count: ' || l_names.count);
end;
如果你需要的东西比数字的列表比较复杂,您可以创建一个对象类型。
这不仅仅是因为级联是缓慢的。 这是在PLSQL动态查询是很慢的。 下面是如何和为什么做到这一点两者很好的书面记录:
问汤姆:我怎样才能做一个变量“列表中的”