目前我的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;
我认为连接查询是不好的做法,所以我想在不使用stings的情况下进行此查询。重写这个的方法是什么?
P.S。也许这里的人可以指出为什么查询连接不好,因为我没有足够的理由来证明这种风格是坏的。
答案 0 :(得分:2)
我的猜测是你先前采取了一些步骤将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;
如果您需要比数字列表更复杂的东西,则可以创建对象类型。
答案 1 :(得分:1)
这不仅仅是连接缓慢。这是plsql中的动态查询真的很慢。这里有关于如何以及为什么要这样做的好文章: