如何在PL/SQL中使用带有VARRAY的SQL'IN'(或'ANY')运算符

And*_*obs 5 sql oracle plsql odp.net varray

我的.NET代码目前正在使用ODP.NET多次调用存储过程来操作许多表中的各个行..NET代码有一组要更改的行.每次调用只改变一个参数,我想将数组从.NET传递给PL/SQL以在多行上运行(行数将改变).

我使用以下方法成功地将数组从.NET传递到PL/SQL:

type number_arr is table of number(10) index by pls_integer;
PROCEDURE "BLAH" (foo IN number_arr);
Run Code Online (Sandbox Code Playgroud)

请注意,我认为number_arr被称为VARRAY,但我对此并不乐观,如果有人想要纠正我,请做(作为评论),但这可能会导致我的困惑.

但是现在,在PL/SQL中,我有许多更新语句,它们看起来像:

UPDATE t SET a = b WHERE a = foo;
Run Code Online (Sandbox Code Playgroud)

当foo不是一个数组时.我现在想写:

UPDATE t SET a = b WHERE a IN (foo);
Run Code Online (Sandbox Code Playgroud)

但是这种语法似乎不起作用.我一直无法找到一个结合使用VARRAY和'IN'(或'ANY'等)的Oracle的例子.我已经看到了如何使用SQL Server做到这一点的一些答案,但我不确定如何将其转换为Oracle.

当然,如果还有其他方法可以将数组从.NET运行到存储过程来执行此操作,那么这也将回答我的问题.我希望通过IN获得效率,所以在PL/SQL中对数组进行迭代(分别调用UPDATE语句)可能无济于事.

All*_*lan 8

您正在使用的数组是关联数组,而不是varray.varrays和嵌套表可以在SQL中使用,但关联数组不能.但是,由于您首先尝试在PL/SQL中执行此操作,因此可以使用批量绑定(将使用关联数组):

PROCEDURE BLAH (foo IN number_arr) is
i number;
begin
   forall i in foo.first .. foo.last
   UPDATE t SET a = b WHERE a = foo(i);
end blah;
Run Code Online (Sandbox Code Playgroud)

如果在数据库中创建number_arr作为varray而不是关联数组,则可以使用表函数:

create type number_arr as varray(10) of number;

CREATE PROCEDURE BLAH (foo IN number_arr) is
begin
   UPDATE t SET a = b WHERE a in (select * from table(foo));
end blah;
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,必须在数据库中定义类型,而不是在包中定义.此外,此方法不一定比使用更快forall.