У меня есть две очень большие таблицы, и мне нужно обработать небольшой набор результатов из этих таблиц. Однако обработка выполняется в нескольких функциях, каждая из которых должна выполнить некоторое объединение, чтобы правильно отформатировать данные.
Мне определенно нужно как-то кэшировать исходный набор результатов, чтобы его можно было повторно использовать в функциях. Что я хотел бы сделать, так это поместить первый набор результатов в одну коллекцию, второй набор результатов в другую коллекцию, а затем манипулировать этими коллекциями с помощью запросов SQL, как если бы они были настоящими таблицами SQL.
Можете подсказать, как это можно сделать?
Ответ 1 · рейтинг 1 · Samuel
Вам нужно создать тип уровня схемы (не внутри пакета) в виде вложенной таблицы. Вы можете заполнить их, а затем использовать в своих запросах как обычные таблицы, используя оператор "table()".
Эта ссылка объясняет, что вам нужно. Быстрый пример
create type foo as table of number;-- or a record type, data%rowtype, whatever
...
myfoo1 foo := foo (1,2,3);
myfoo2 foo := foo(3,4,5)
select column_value
into bar
from table(foo1) join table(foo2) using (column_value)
Ответ 2 · рейтинг 5 · OMG Ponies
Звучит как работа для временных таблиц:
CREATE GLOBAL TEMPORARY TABLE table_name (...) ON ...
У ON есть два варианта с разными последствиями:
ON COMMIT DELETE ROWS указывает, что временная таблица будет специфичной для транзакции. Данные сохраняются в таблице до момента окончания транзакции. Если вы завершаете транзакцию, база данных усекает таблицу (удаляет все строки). Предположим, если вы выполните коммит или запустите ddl, данные во временной таблице будут потеряны. Это опция по умолчанию.
ON COMMIT PRESERVE ROWS указывает, что временная таблица будет зависеть от сеанса. Данные сохраняются в таблице до момента окончания сеанса. Если вы завершаете сеанс, база данных усекает таблицу (удаляет все строки). Предположим, вы ввели exit в SQL*Plus, тогда данные во временной таблице будут потеряны.
Ссылка:
- ASKTOM
- Создать временную таблицу в Oracle
... но возможно, вам не нужно использовать временные таблицы. Производные таблицы/встроенные представления/подзапросы (возможно, конвейерные) могут делать то, что вы хотите, но информация расплывчата, поэтому я не могу рекомендовать конкретный подход.
Ответ 3 · рейтинг 3 · APC
Если ваши коллекции объявлены с типом SQL, вы можете использовать их в операторах SQL с функцией TABLE(). В Oracle 10g мы можем объединять коллекции с помощью оператора MULTISET UNION. В следующем коде показаны примеры обоих методов...
SQL> declare
2 v1 sys.dbms_debug_vc2coll;
3 v2 sys.dbms_debug_vc2coll;
4 v3 sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll();
5 begin
6 select ename
7 bulk collect into v1
8 from emp;
9 select dname
10 bulk collect into v2
11 from dept;
12
13 -- manipulate connects using SQL
14
15 for r in ( select * from table(v1)
16 intersect
17 select * from table(v2)
18 )
19 loop
20 dbms_output.put_line('Employee '|| r.column_value ||' has same name as a department');
21 end loop;
22
23 -- combine two collections into one
24
25 dbms_output.put_line('V3 has '|| v3.count() ||' elements');
26 v3 := v1 multiset union v2;
27 dbms_output.put_line('V3 now has '|| v3.count() ||' elements');
28 end;
29 /
Employee SALES has same name as a department
V3 has 0 elements
V3 now has 23 elements
PL/SQL procedure successfully completed.
SQL>
Существует ряд других подходов, которые вы можете использовать. Как правило, лучше использовать SQL, а не PL/SQL, поэтому предложение OMG Ponies о временных таблицах может оказаться уместным. Это действительно зависит от точных деталей ваших потребностей в обработке.