Как использовать ассоциативный массив Oracle в запросе SQL

StackOverflow https://stackoverflow.com/questions/1715978

Вопрос

ODP.Net предоставляет возможность передавать ассоциативные массивы в качестве параметров в хранимую процедуру Oracle из C#.Это хорошая функция, если вы не пытаетесь использовать данные, содержащиеся в этом ассоциативном массиве, в запросе sql.

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

Итак, вопрос в том, какие методы вы бы использовали для преобразования параметра ассоциативного массива PL/SQL во что-то, что внутри процедуры можно использовать в следующем операторе sql:

OPEN refCursor FOR
SELECT T.*
FROM   SOME_TABLE T,
       ( SELECT COLUMN_VALUE V
         FROM   TABLE( associativeArray )
       ) T2
WHERE  T.NAME = T2.V;

Для целей этого примера «associativeArray» представляет собой простую таблицу varchar2(200), индексированную PLS_INTEGER.В C# параметр associativeArry заполняется строкой [].

Не стесняйтесь обсуждать другие способы сделать это, помимо использования ассоциативного массива, но знайте заранее, что эти решения не будут приняты.Тем не менее, мне интересно увидеть другие варианты.

Это было полезно?

Решение

Я бы создал такой тип базы данных:

create type v2t as table of varchar2(30);
/

И далее по процедуре:

FOR i IN 1..associativeArray.COUNT LOOP
    databaseArray.extend(1);
    databaseArray(i) := associativeArray(i);
END LOOP;

OPEN refCursor FOR
SELECT T.*
FROM   SOME_TABLE T,
       ( SELECT COLUMN_VALUE V
         FROM   TABLE( databaseArray )
       ) T2
WHERE  T.NAME = T2.V;

(где dataArray объявлен как тип v2t.)

Другие советы

Вы не можете использовать ассоциативные массивы в области SQL — их можно использовать только в области PL/SQL.

Один из методов — сопоставить ассоциативный массив с коллекцией (которую можно использовать в области SQL, если тип коллекции определен в области SQL, а не в области PL/SQL).

SQL:

CREATE TYPE VARCHAR2_200_Array_Type AS TABLE OF VARCHAR2(200);
/

ПЛ/SQL

DECLARE
  TYPE associativeArrayType IS TABLE OF VARCHAR2(200) INDEX BY PLS_INTEGER;
  i                PLS_INTEGER;
  associativeArray associativeArrayType;
  array            VARCHAR2_200_Array_Type;
  cur              SYS_REFCURSOR;
BEGIN
  -- Sample data in the (sparse) associative array
  associativeArray(-2) := 'Test 1';
  associativeArray(0)  := 'Test 2';
  associativeArray(7)  := 'Test 3';

  -- Initialise the collection
  array := VARCHAR2_200_Array_Type();

  -- Loop through the associative array
  i := associativeArray.FIRST;
  WHILE i IS NOT NULL LOOP
    array.EXTEND(1);
    array(array.COUNT) := associativeArray(i);
    i := associativeArray.NEXT(i);
  END LOOP;

  -- Use the collection in a query
  OPEN cur FOR
    SELECT *
    FROM   your_table
    WHERE  your_column MEMBER OF array;
END;
/
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top