【问题标题】:How to use SQL 'IN' (or 'ANY') operator with VARRAY in PL/SQL如何在 PL/SQL 中将 SQL“IN”(或“ANY”)运算符与 VARRAY 一起使用
【发布时间】:2011-10-06 09:37:59
【问题描述】:

我的 .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);

请注意,我相信 number_arr 被称为 VARRAY,但我对此并不积极,如果有人想纠正我,请这样做(作为评论),但这可能会导致我的困惑。

但是现在,在 PL/SQL 中,我有许多以前看起来像这样的更新语句:

UPDATE t SET a = b WHERE a = foo;

当 foo 不是数组时。我现在想写:

UPDATE t SET a = b WHERE a IN (foo);

但这种语法似乎不起作用。而且我一直无法找到结合使用 VARRAY 和“IN”(或“ANY”等)的 Oracle 示例。我已经看到了一些关于如何使用 SQL Server 执行此操作的答案,但我不确定如何将其转换为 Oracle。

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

【问题讨论】:

    标签: sql oracle plsql odp.net varray


    【解决方案1】:

    您使用的数组是associative array,而不是可变数组。可变数组和嵌套表可以在 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;
    

    如果您在数据库中将 number_arr 创建为可变数组而不是关联数组,则可以改用 table 函数:

    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;
    

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

    【讨论】:

    • 我相信在你最后的代码 sn-p 中,table(foo) 需要是table(cast(foo as number_arr))。但总的来说,很好的答案。
    • 你是对的!我认为在过去的某个时候需要 CAST,但在 10.2.0.4 中的测试表明现在不需要。
    • 感谢您的回答。知道 forall 至少会有同样快的帮助,所以我不介意为我的许多案例编写循环。但是,我确实从我的实际代码中简化了我的问题,并且仍然有一些地方我想使用带有“IN”或“ANY”运算符的关联数组。这可能吗?
    • @Andy:不,您不能将关联数组与inany 一起使用。关联数组仅适用于 PL/SQL,因此它们永远不能在 SQL 中使用(即使在 PL/SQL 中执行)。
    猜你喜欢
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多