Oracle 在“in”子句中使用bind变量
我想将数字列表查询到plsql变量中,并在另一个sql查询的in子句中使用该变量。我在下面创建了一个我想做的测试用例 我在谷歌上找到了解决方案,我想这一定是可能的,但我就是没能让它运行。请帮我找到一个编译解决方案Oracle 在“in”子句中使用bind变量,oracle,plsql,oracle10g,bind-variables,Oracle,Plsql,Oracle10g,Bind Variables,我想将数字列表查询到plsql变量中,并在另一个sql查询的in子句中使用该变量。我在下面创建了一个我想做的测试用例 我在谷歌上找到了解决方案,我想这一定是可能的,但我就是没能让它运行。请帮我找到一个编译解决方案 CREATE OR REPLACE PROCEDURE PROCEDURE1 as type t_id is table of number; v_ids t_id; v_user_ids number; BEGIN -- fill variable v_id with
CREATE OR REPLACE PROCEDURE PROCEDURE1
as
type t_id is table of number;
v_ids t_id;
v_user_ids number;
BEGIN
-- fill variable v_id with id's, user_id is of type number
select user_id
bulk collect into v_ids
from user_users;
-- then at a later stage ... issue a query using v_id in the in clause
select user_id into v_user_ids from user_users
-- this line does not compile ( local collection type not allowed in SQL statements)
where user_id in ( v_ids );
END PROCEDURE1;
使用SQL类型:
SQL> create type t_id is table of number;
2 /
Type created.
SQL> CREATE OR REPLACE PROCEDURE PROCEDURE1
2 as
3 v_ids t_id;
4 v_user_ids number;
5 BEGIN
6
7 -- fill variable v_id with id's, user_id is of type number
8 select user_id
9 bulk collect into v_ids
10 from user_users
11 where user_id between 100 and 120;
12
13 select user_id into v_user_ids
14 from user_users
15 where user_id in (select /*+ cardinality(t, 10) */ t.column_value from table(v_ids) t)
16 and rownum = 1;
17
18 dbms_output.put_line(v_user_ids);
19
20 END PROCEDURE1;
21 /
Procedure created.
SQL> exec procedure1
100
其中cardinalityt,10应该是关于数组中有多少元素的合理猜测
注:
使用无界批量收集,如您所拥有的:
8 select user_id
9 bulk collect into v_ids
10 from user_users;
如果您的数组最终可能会有数千行或更多行,这通常不是很好,因为您在内存上施加了太多压力,最终会使代码崩溃。最好为..使用一个显式游标open x。。使用limit子句(即fetch x bulk collect into v_ids limit 100)在循环中进行批量提取,并分批处理,例如100-1000。这可能是一个简化的演示,但在您给出的示例中,您是否可以将两个查询合并为一个查询?选择从…起从中选择用户id的位置。。。?或者执行连接?是的,这被简化了,可能没有意义。我需要编译这个示例-我在这行中得到一个错误:v_id中的user_id使用的是sql数组,而不是plsql嵌套表不是您的选项?如果是的话,我们可以使用TABLE函数来解决这个问题,尽管您的上一条语句没有意义,因为它是select-into,所以您的结果是一行?如果您的实际sql是select max或rownum=1或其他值,则可以使用。slq数组:我声明“type t_id是varray1000 of number;”并使用“表v_id中的where user_id;”但这不是编译either@user1863377我的意思是,创建类型t_id作为数字表;而不是将其放在PLSQL块中。这可以接受吗?太好了,内部选择就可以了!我可以避免创建类型。。。?是否可以重用oracle已经提供的类型?-真正的代码确实会以1000个批次通过1亿条记录。我是一个java爱好者,出于性能原因,需要在plsql中执行此操作。您可以查看数据库中的可用内容选择owner、type_name、coll_type、upper_bound、precision、scale from all_coll_type,其中elem_type_name=‘NUMBER’;然后选择一个,例如v_ids KU$\u OBJNUMSET;。只要记住,使用Oracle拥有的SYS one,它的主题可能会在Oracle的未来版本中消失或更改:1000个批次和性能对我来说是相互排斥的。如果您确实有大量的记录,那么考虑将需要传递给代码的值插入到全局临时表中,并使用尽可能少的SQL语句加入它。@ DavidAldridge TRUE,如果您可以将它作为1 SQL更好,但如果没有,那么有限制的批量收集比循环好,比没有限制的批量收集更安全。