Oracle PL/SQL
August 9
Массивы в Oracle
В Oracle массив — это структура, которая позволяет хранить набор значений в одной переменной.
Представьте, что у вас есть список номеров школ — вместо того чтобы заводить 10 переменных school1, school2, ..., мы кладём все значения в один контейнер и работаем с ними как с единым объектом.
Массивы в Oracle особенно полезны в PL/SQL, при передаче данных между процедурами, а также при интеграции через OCI (Oracle Call Interface).
Основные типы массивов в Oracle
VARRAY (Variable-size array)
- Хранит фиксированное _максимальное_ количество элементов.
- Данные хранятся вместе с родительской записью (inline).
- Хорошо для небольших списков, когда нужен фиксированный лимит.
NESTED TABLE
- Размер не ограничен.
- Данные могут храниться отдельно от основной таблицы (out-of-line).
- Удобно, когда список может расти.
INDEX-BY TABLE (Associative array)
- Хранится только в памяти (не в таблице).
- Индексация по числу или строке.
- Используется в PL/SQL для временных структур.
TABLE OF TYPE
- Пользовательский тип данных, который можно использовать в схемах, пакетах и т. д.
- Часто используется для передачи коллекций между процедурами.
OCI Массивы (SYS.OCI...)
- Специальные структуры для обмена данными с клиентскими приложениями через OCI.
- Применяются при работе с драйверами C/C++ или при пакетной загрузке данных.
Массив школ в SYS.ODCINumberList (OCI совместимый тип)
В Oracle уже есть готовые коллекции в пакете SYS, которые используются и в OCI — например:
Они часто применяются для bulk insert, передачи в SQL из PL/SQL, и для интеграции с внешними клиентами.
Сравнение
Где применяется
- Списки — например, список номеров школ для обработки.
- Передача параметров в процедуру/функцию.
- Пакетная загрузка данных в таблицу.
- Интеграция с внешними приложениями через OCI.
Пример SYS.ODCINumberList
DECLARE
v_schools SYS.ODCINumberList := SYS.ODCINumberList(101, 102, 103);
BEGIN
v_schools.EXTEND;
v_schools(4) := 104;
FOR i IN 1 .. v_schools.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('School #' || v_schools(i));
END LOOP;
END;Пример TYPE
CREATE OR REPLACE TYPE school_varray AS VARRAY(5) OF NUMBER;
DECLARE
v_schools school_varray := school_varray(201, 202);
BEGIN
v_schools.EXTEND;
v_schools(3) := 203;
DBMS_OUTPUT.PUT_LINE('Total schools: ' || v_schools.COUNT);
END;Пример nested table
CREATE OR REPLACE TYPE school_list AS TABLE OF NUMBER;
DECLARE
v_schools school_list := school_list(101, 102, 103);
BEGIN
FOR i IN 1 .. v_schools.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('School #' || v_schools(i));
END LOOP;
END;
Пример INDEX-BY TABLE
DECLARE TYPE school_index IS TABLE OF VARCHAR2(100) INDEX BY PLS_INTEGER; v_schools school_index; BEGIN v_schools(1) := 'School #301'; v_schools(2) := 'School #302'; DBMS_OUTPUT.PUT_LINE(v_schools(1)); DBMS_OUTPUT.PUT_LINE(v_schools(2)); END;
Пример SYS.OCI...
DECLARE
v_schools SYS.ODCINumberList := SYS.ODCINumberList(101, 102, 103);
BEGIN
v_schools.EXTEND;
v_schools(4) := 104;
FOR i IN 1 .. v_schools.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('Школа №' || v_schools(i));
END LOOP;
END;