Как использовать оператор SQL IN или ANY с VARRAY в PL / SQL - PullRequest
5 голосов
/ 15 июля 2011

Мой код .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;

, когдаФу не был массивом.Теперь я хочу написать:

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

Но этот синтаксис, похоже, не работает.И я не смог найти пример для Oracle, который сочетает в себе использование VARRAY и «IN» (или «ЛЮБОЙ» и т. Д.).И я видел несколько ответов о том, как сделать это с SQL Server, но я не уверен, как перевести это в Oracle.

Конечно, если есть какой-то другой способ получить массив из.NET для хранимой процедуры, чтобы сделать это, что также ответит на мой вопрос.Я стремлюсь повысить эффективность с IN, поэтому что-то, что перебирает массив в PL / SQL (для вызова операторов UPDATE отдельно), вероятно, не поможет.

1 Ответ

8 голосов
/ 16 июля 2011

Используемый вами массив - это ассоциативный массив , а не массив.В 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 какВ базе данных 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;

Обратите внимание, что в этом случае тип должен быть определен в базе данных, а не в вашем пакете.Кроме того, этот метод не обязательно будет быстрее, чем использование forall.

...