用典型的SQL替换FORALL语句

时间:2014-05-02 15:22:02

标签: sql oracle plsql

我的程序代码如下:

TYPE users_table IS TABLE OF tt_users.id%TYPE INDEX BY BINARY_INTEGER;

PROCEDURE remove_users(user_ids users_table) IS
   --...
BEGIN
   --...
    FORALL i IN 1..user_ids.COUNT DELETE FROM tt_users WHERE id = user_ids(i);  
END;

有没有办法用典型的SQL替换FORALL语句来提高性能?

3 个答案:

答案 0 :(得分:1)

由于您使用的是11.1或11.2,因此无法在SQL语句中使用关联数组。您可以将集合类型重新定义为嵌套表

CREATE TYPE users_tbl
    IS TABLE OF NUMBER;

如果您这样做,您可以重新定义您的程序以接受新集合的实例

PROCEDURE remove_users(user_ids users_tbl) IS
   --...
BEGIN
   --...
    DELETE FROM tt_users 
     WHERE id IN (SELECT column_value
                    FROM TABLE( user_ids ));  
END;

但是,如果您进行了这些更改,那么您不太可能看到有意义的性能提升。在这两种情况下,您将在PL / SQL中收集一个集合,将其批量传递给SQL引擎,并让SQL引擎在一次调用中删除多行。

答案 1 :(得分:0)

你能这样做吗?

delete from tt_users
    where id in (select id from user_ids);

答案 2 :(得分:0)

如果您的users_table类型处于架构级别(不在包中),您应该可以从中进行选择:

 select id from table(user_ids);

因此也从中删除:

delete from tt_users
where id in (select id from table(user_ids));

如果不起作用,你可以尝试将你的id放在一个字符串中,然后在where子句中使用这个字符串:

 mystr := ',1,2,3,5,'

 delete from tt_users 
 where instr(mystr, ','||id ||',') > 0

但这个限制为4k。