Как использовать ассоциативный массив Oracle в запросе SQL
-
19-09-2019 - |
Вопрос
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;
/