Oracle стандартные типы массивов

Обновлено: 07.07.2024

Пришло, я думаю, время разобрать составной тип, который, по моему мнению, является наиболее мощным и простым средством скоростной обработки больших массивов данных. Такой составной тип имеет название TABLE! Рассмотрим его синтаксис: (он подобен синтаксису RECORD)

Вот так просто объявить составной тип TABLE! В своей сути это одномерный массив скалярного типа. Он не может содержать тип RECORD или другой тип TABLE. Но может быть объявлен от любого другого стандартного типа. И это еще не все! TABLE может быть объявлен от атрибута %ROWTYPE! Вот где скрывается, по истине огромная мощь, этого типа данных! Но пока, все по порядку. Тип TABLE, можно представить как одну из разновидностей коллекции. Хотя в более глубоком понимании это не совсем так. При первом рассмотрении он похож на массив языка C. Массив TABLE индексируется типом BINARY_INTEGER и может содержать, что-то вроде - 2,147,483,647 - 0 - + 2,147,483,647 как в положительную, так и в отрицательную часть. Начинать индексацию можно с 0 или 1 или любого другого числа. Если массив будет иметь разрывы, то это не окажет какой-либо дополнительной нагрузки на память. Так же следует помнить, что для каждого элемента, например, типа VARCHAR2 будет резервироваться столько памяти, сколько вы укажете, по этому определяйте размерность элементов по необходимости. Скажем не стоит объявлять VARCHAR2(255), если хотите хранить строки менее 100 символов! :) Итак, давайте объявим массив и посмотрим, как он работает. Запишем такой блок:

Получаем после обработки в SQL*Plus:

Рассмотрим, что же здесь происходит. Мы объявили две одномерные коллекции m_SmplTable, m_SmplTblData, одна из них содержит элементы размерностью VARCHAR2(128), другая DATE. Затем объявили две переменные данного типа - MY_TBL, MY_TBL_DT и присвоили первому элементу строкового массива значение "Buber", а второму элементу массива дат, значение текущей даты минус 1. Результат вывели на консоль! Вот собственно и все. При этом хорошо видно, что тип TABLE очень схож с таблицей БД и содержит обычно два ключа KEY и VALUE, ключ и значение. Ключ имеет тип BINARY_INTEGER:

В нашем случае имеет место:

  1. Число строк таблицы ни чем не ограничено. Единственное ограничение это значения, которые могут быть представлены типом BINARY_INTEGER.
  2. Порядок элементов таблицы PL/SQL не обязательно должен быть строго определен. Эти элементы хранятся в памяти не подряд как массивы и по этому могут вводится с произвольными ключами.
  3. Ключи, используемые в таблице PL/SQL, не обязательно должны быть последовательными. В качестве индекса таблицы может быть использовано любое значение или выражение имеющее тип BINARY_INTEGER.

Здесь мы объявили коллекцию из строковых переменных, и с помощью известного вам цикла FOR записали с 1-го по 10-й элемент значениями исходный плюс пять. Затем мы вывели на экран пятый элемент, как и следовало ожидать его значение равно 10 (5+5). Вот один из способов наполнения массива значениями. Но этот способ бесполезен и показан в качестве примера. А, вот следующий пример более осмыслен. Перепишем блок из предыдущего шага вот так:

Здесь мы объявили коллекцию, с типом запись из таблицы CUSTOMERS! И получили тот же результат как в прошлый раз, но более элегантно! Итак, объявляем тип:

Это значит, что каждая строка коллекции содержит полную запись из таблицы БД CUSTOMERS. Замечательно. Далее 100 элементу массива присваиваем значение записи таблицы с индексом 2108. Вот так это выглядит изнутри:

Обращаться к отдельному элементу (полю) записи можно через точечную нотацию. Что мы и проделали с вами в примере! Так же скажу, что используя привязку таблиц PL/SQL к массивам интерфейса OCI можно достичь очень высокой скорости передачи данных в клиентских приложениях БД. В следующий раз рассмотрим атрибуты таблиц PL/SQL.

Кроме типов данных Oracle7, PL/SQL поддерживает несколько дополнительных типов данных и позволяет использовать в своих конструкциях некоторые основные типы с большим диапазоном.

Рассмотрим подробнее типы данных TABLE и RECORD, позволяющие создавать одномерные массивы и записи, широко используемые в программах PL/SQL.

Таблицы PL/SQL

Для описания типа данных TABLE используется синтаксис:

TYPE type_name IS TABLE OF < column_type | variable%TYPE |

table.column%TYPE > [NOT NULL] INDEX BY BINARY_INTEGER;

Имя (например, name_plsql_table), которое описывается табличным типом данных, называется таблицей PL/SQL. Это описание, размещаемое в разделе DECLARE, имеет вид: name_plsql_table type_name;
Ссылки на строки таблицы PL/SQL осуществляются аналогично ссылкам на элементы одномерного массива: name_plsql_table(index), где index принадлежит типу BINARY_INTEGER. Например, для ссылки на третью строку в таблице PL/SQL «ename_tab» следует написать: ename_tab(3).

Для присвоения значения конкретной строке таблицы PL/SQL используется синтаксис: name_plsql_table(index) := expr;

Для ввода в таблицу PL/SQL значений из какого-либо столбца базовой таблицы или представления, а также для выборки значений из таблицы PL/SQL, необходимо использовать цикл.

Записи PL/SQL

Если создаваемая запись (sotr) соответствует описанию столбцов какой-либо базовой таблицы (например, kadry), то ее объявление можно осуществить в разделе DECLARE с помощью атрибута %ROWTYPE: sotr kadry%ROWTYPE;

В противном случае для объявления записи необходимо сначала определить ее тип данных. Для описания типа данных RECORD используется синтаксис:

При объявлении типа записи можно присвоить ее полям некоторые значения. Если же для поля вводится ограничение NOT NULL (для предотвращения назначения пустых значений), то этому полю надо обязательно присвоить значение. Например:

TYPE SotrRecTyp IS RECORD (nomer NUMBER(4) NOT NULL := 1001,

familiy CHAR(20), dolgnost CHAR(14), otdel NUMBER(3) := 102);

Объявление создаваемой записи (например, name_plsql_record) производится в разделе DECLARE и имеет вид: name_plsql_record type_name;
Ссылки на отдельные поля записи осуществляются так: name_plsql_record.field_name;
Для присвоения значения конкретному полю записи используется синтаксис: name_plsql_record.field_name := expr;

Примеры использования записей в программах PL/SQL приведены ниже.
Для ввода в таблицу PL/SQL значений из какого-либо столбца базовой таблицы или представления, а также для выборки значений из таблицы PL/SQL, необходимо использовать цикл.

Переменные, константы и выражения PL/SQL

В программах PL/SQL могут использоваться переменные и константы, описываемые в разделе DECLARE с помощью конструкции вида: variable_name [CONSTANT] type_name [NOT NULL] [ < := | DEFAULT >expr ]
Например:

Запись опубликована 08.04.2010 в 5:50 дп и размещена в рубрике Oracle7 краткий справочник. Вы можете следить за обсуждением этой записи с помощью ленты RSS 2.0. Можно оставить комментарий или сделать обратную ссылку с вашего сайта.

Каждое значение, которым манипулирует база данных Oracle, имеет тип данных. Тип данных значения связывает фиксированный набор свойств со значением. Используя эти свойства, Oracle обрабатывает значения одного типа данных иначе, чем значения другого. Например, вы можете добавить значения типа данных NUMBER, но не значения типа данных CHAR.

База данных Oracle предоставляет ряд встроенных типов данных, а также несколько категорий для пользовательских типов, которые могут использоваться в качестве типов данных.

Встроенные типы данных Oracle

В следующей таблице приведены встроенные типы данных Oracle.

Типы Описание Размер
VARCHAR2 (размер [BYTE | CHAR]) Строка символов переменной длины. От 1 байта до 4КБ.
NVARCHAR2 (размер) Строка символов Unicode переменной длины, имеющая символы максимального размера. Максимальный размер определяется национальным набором символов с верхним пределом 4000 байтов. Вы должны указать размер для NVARCHAR2.
NUMBER [(p [, s])] Число с точностью p и шкалой s.
Диапазон р: от 1 до 38.
Диапазоны s: от -84 до 127.
Точность и масштаб указаны в десятичных цифрах.
Значение NUMBER требует от 1 до 22 байтов.
FLOAT [(p)] Значение FLOAT внутренне представлено как NUMBER.
Диапазон значений p: от 1 до 126 двоичных цифр.
Значение FLOAT требует от 1 до 22 байтов.
ДОЛГО Символьные данные переменной длины до 2 гигабайт, используемые для обратной совместимости. 2 31 -1 байт
ДАТА Действительный диапазон дат: с 1 января 4712 г. до н.э. до 31 декабря 9999 г. н.э.
Формат по умолчанию определяется явно параметром NLS_DATE_FORMAT или неявно параметром NLS_TERRITORY.
Размер фиксируется в 7 байтов.
BINARY_FLOAT 32-битное число с плавающей точкой. Этот тип данных требует 4 байта.
BINARY_DOUBLE 64-битное число с плавающей запятой. Этот тип данных требует 8 байтов.
TIMESTAMP [(fraal_seconds_precision)] Этот тип данных содержит поля даты и времени YEAR, MONTH, DAY, HOUR, MINUTE и SECOND. Он содержит доли секунды, но не имеет часового пояса. Размер составляет 7 или 11 байт, в зависимости от точности.
TIMESTAMP [(фракция_seconds_precision)] с зоной времени Этот тип данных содержит поля даты и времени YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, TIMEZONE_HOUR и TIMEZONE_MINUTE. У него есть доли секунды и явный часовой пояс. Размер фиксируется в 13 байт.
ИНТЕРВАЛЬНЫЙ ГОД [(year_precision)] ДО МЕСЯЦА Сохраняет период времени в годах и месяцах, где year_precision - это количество цифр в поле YEAR datetime.
Допустимые значения: от 0 до 9. По умолчанию установлено значение 2.
Размер фиксируется в 5 байтах.
ИНТЕРВАЛЬНЫЙ ДЕНЬ [(day_precision)] ДО ВТОРОГО [(фракция_презентация_precision)] Сохраняет период времени в днях, часах, минутах и секундах, где
day_precision - это максимальное количество цифр в поле DAY datetime.
Допустимые значения: от 0 до 9. По умолчанию установлено значение 2.
Размер фиксируется в 11 байтов.
RAW (размер) Необработанные двоичные данные байтов размера длины. Максимальный размер 2000 байт
ДЛИННАЯ СЫРЬЯ Необработанные двоичные данные переменной. Размер до 2 гигабайт.
ROWID Уникальный адрес (представляющий строку из 64 строк) строки в ее таблице.
UROWID [(размер)] Логический адрес строки (представляющей строку из 64 строк) организованной по индексу таблицы. Максимальный размер и значение по умолчанию составляет 4000 байтов.
CHAR [(размер [BYTE | CHAR])] Символьные данные фиксированной длины размером в байтах или символах. Максимальный размер составляет 2000 байтов или символов. Минимальный размер по умолчанию - 1 байт.
NCHAR [(размер)] Данные символа фиксированной длины символов размера длины. Количество байтов может быть в два раза больше для кодирования AL16UTF16 и в три раза больше для кодирования UTF8. Максимальный размер определяется национальным набором символов с верхним пределом в 2000 байтов. Минимальный размер по умолчанию - 1 символ.
CLOB Большой символьный объект, содержащий однобайтовые или многобайтовые символы. Максимальный размер (4 гигабайта - 1) * (размер блока базы данных).
NCLOB Большой символьный объект, содержащий символы Юникода. Максимальный размер (4 гигабайта - 1) * (размер блока базы данных). Хранит данные национального набора символов.
большой двоичный объект Большой двоичный объект. Максимальный размер 4 гигабайта.
BFILE Содержит локатор для большого двоичного файла, хранящегося за пределами базы данных. Максимальный размер 4 гигабайта.

Типы данных персонажей Oracle

Тип данных CHAR определяет символьную строку фиксированной длины. Если вы вставите значение, которое короче длины столбца, Oracle пустым образом подставит значение в длину столбца, а если значение слишком длинное для столбца, Oracle вернет ошибку. Следующие типы данных используются для символьных данных:

Тип данных Oracle NUMBER

НОМЕР Тип данных:

Тип данных NUMBER хранит нулевые, положительные и отрицательные фиксированные числа.

Числовой формат с фиксированной точкой:

  • Где p - точность, до 20 цифр от 100 до 100, что эквивалентно 39 или 40 десятичным знакам в зависимости от положения десятичной точки.
  • s - масштаб, масштаб может варьироваться от -84 до 127.
  • Положительная шкала - это число значащих цифр справа от десятичной точки и включая наименее значимую цифру.
  • Отрицательная шкала - это число значащих цифр слева от десятичной точки, но не включая наименее значимую цифру.

Примеры:

Тип данных FLOAT:

Тип данных FLOAT является подтипом NUMBER. Вы можете указать это с точностью или без. Масштаб не может быть указан, но интерпретируется из данных. Каждое значение FLOAT требует от 1 до 22 байтов.

В следующем примере показана разница между NUMBER и FLOAT:

В приведенном выше примере возвращаемое значение FLOAT не может превышать 5 двоичных цифр. Таким образом, 123,45 округляется до 120, который имеет только две значащие десятичные цифры, требующие только 4 двоичных цифр.

Числа с плавающей точкой:

Термин с плавающей запятой происходит от того факта, что не существует фиксированного количества цифр до и после десятичной точки; то есть десятичная точка может плавать. Показатель степени может необязательно использоваться после числа для увеличения диапазона, например, 1.777 e -20 .

Пример:

В базе данных Oracle есть два числовых типа данных исключительно для чисел с плавающей запятой:

BINARY_FLOAT:
BINARY_FLOAT - это 32-битный тип данных с плавающей запятой с одинарной точностью. Каждое значение BINARY_FLOAT требует 4 байта.

BINARY_DOUBLE:
BINARY_DOUBLE - это 64-битный тип данных с плавающей запятой с двойной точностью. Каждое значение BINARY_DOUBLE требует 8 байтов.

Примеры:

Значение BINARY_FLOAT BINARY_DOUBLE
Максимальное положительное конечное значение 3.40282E + 38F 1.79769313486231E + 308
Минимальное положительное конечное значение 1.17549E-38F 2.22507485850720E-308

ДОЛГОЙ Тип данных
Используйте столбцы LOB (CLOB, NCLOB, BLOB), поскольку столбцы LONG поддерживаются только для обратной совместимости.

В столбцах LONG хранятся строки символов переменной длины, содержащие до 2 гигабайт -1 или 2 31 -1 байтов. Длинные столбцы имеют многие характеристики столбцов VARCHAR2. Вы можете использовать длинные столбцы для хранения длинных текстовых строк. Длина значений LONG может быть ограничена объемом памяти, доступной на вашем компьютере. ДЛИННЫЕ литералы формируются, как описано для «Текстовых литералов».

Типы данных даты и времени

Ниже приведены типы данных datetime:

  • ДАТА
  • TIMESTAMP
  • TIMESTAMP с зоной времени
  • TIMESTAMP с локальной зоной времени

Значения типов данных datetime иногда называют datetime.

Поля даты и значения:

Поле даты и времени Допустимые значения для даты и времени Допустимые значения для INTERVAL
ГОД От -4712 до 9999 (исключая год 0) Любое положительное или отрицательное целое число
МЕСЯЦ 01 до 12 От 0 до 11
ДЕНЬ С 01 по 31 (ограничено значениями MONTH и YEAR в соответствии с правилами текущего параметра календаря NLS) Любое положительное или отрицательное целое число
ЧАС От 00 до 23 От 0 до 23
МИНУТЫ От 00 до 59 От 0 до 59
ВТОРОЙ От 00 до 59,9 (n), где 9 (n) - это точность долей времени в секундах. 9 (n) часть не относится к DATE. От 0 до 59,9 (n), где 9 (n) - точность интервала долей секунд
TIMEZONE_HOUR От -12 до 14 (этот диапазон учитывает изменения летнего времени.) Неприменимо для DATEor TIMESTAMP. Непригодный
TIMEZONE_MINUTE От 00 до 59. Не применимо для даты или времени. Непригодный
TIMEZONE_REGION Запросите столбец TZNAME представления словаря данных V $ TIMEZONE_NAMES. Не применимо для DATE или TIMESTAMP. Непригодный
TIMEZONE_ABBR Запросите столбец TZABBREV представления словаря данных V $ TIMEZONE_NAMES. Не применимо для DATE или TIMESTAMP. Непригодный

ДАТА Тип данных:

Тип данных DATE хранит информацию о дате и времени (представленную как символьными, так и числовыми типами данных). Для каждого значения DATE Oracle хранит год, месяц, день, час, минуту и секунду.

Используя юлианские дни:

Юлианский номер дня - это количество дней с 1 января 4712 года до нашей эры. Вы можете использовать модель формата даты "J" с функциями даты TO_DATE и TO_CHAR для преобразования между значениями Oracle DATE и их юлианскими эквивалентами.

Значения даты по умолчанию:

  • Год - это текущий год, возвращаемый SYSDATE.
  • Месяц является текущим месяцем, возвращаемым SYSDATE.
  • День 01 (первый день месяца).
  • Час, минута и секунда - все 0.

Функция TO_DATE преобразует символьное или числовое значение в дату.

Вы можете использовать модель формата даты "J" с функциями даты TO_DATE и TO_CHAR для преобразования между значениями Oracle DATE и их юлианскими эквивалентами. Следующий оператор возвращает юлианский эквивалент 1 января 2015 года:

Тип данных TIMESTAMP:
Тип данных TIMESTAMP является расширением типа данных DATE и хранит год, месяц и день типа данных DATE, а также значения часов, минут и секунд. Это полезно для хранения точных значений времени, а также для сбора и оценки информации о дате по географическим регионам.

TIMESTAMP с временной зоной Тип данных:
TIMESTAMP WITH TIME ZONE - это вариант TIMESTAMP, который включает в себя имя региона часового пояса или смещение часового пояса в своем значении. Это полезно для сохранения информации о часовом поясе.

TIMESTAMP с локальной зоной времени Тип данных:

TIMESTAMP с локальной зоной времени - еще один вариант TIMESTAMP, чувствительный к информации о часовых поясах. Он отличается от TIMESTAMP WITH TIME ZONE тем, что данные, хранящиеся в базе данных, нормализуются к часовому поясу базы данных, а информация о часовом поясе не сохраняется как часть данных столбца. Когда пользователь получает данные, Oracle возвращает их в часовом поясе локального сеанса пользователя. Этот тип данных полезен для информации о дате, которая всегда должна отображаться в часовом поясе клиентской системы в двухуровневом приложении.

ИНТЕРВАЛ ГОДА В МЕСЯЦ Тип данных:

ИНТЕРВАЛ ГОДА В МЕСЯЦ хранит период времени, используя поля даты и года ГОД и МЕСЯЦ. Этот тип данных полезен для представления разницы между двумя значениями даты и времени, когда значимы только значения года и месяца.

ДЕНЬ ИНТЕРВАЛА ДЛЯ ВТОРОГО Типа данных:

INTERVAL DAY TO SECOND хранит период времени в виде дней, часов, минут и секунд. Этот тип данных полезен для представления точной разницы между двумя значениями даты и времени.

  • day_precision - количество цифр в поле даты и времени DAY. Допустимые значения: от 0 до 9. По умолчанию установлено значение 2.
  • fraal_seconds_precision - количество цифр в дробной части поля ВРЕМЯ datetime. Допустимые значения: от 0 до 9. По умолчанию установлено значение 6.

Типы данных ANSI, DB2 и SQL / DS

Oracle распознает имя типа данных ANSI или IBM, которое отличается от имени типа данных Oracle Database, и преобразует тип данных в эквивалентный тип данных Oracle. Следующая таблица показывает конверсии :,

Тип данных ANSI SQL Тип данных Oracle
СИМВОЛЫ (п)
СИМ (п)
СИМ (п)
VARING CHARACTER (n)
CHAR VARYING (n)
VARCHAR2 (п)
НАЦИОНАЛЬНЫЙ ХАРАКТЕР (n)
НАЦИОНАЛЬНЫЙ ЧАР (n)
NCHAR (п)
NCHAR (п)
НАЦИОНАЛЬНЫЙ ХАРАКТЕР ИЗМЕНЕНИЯ (n)
НАЦИОНАЛЬНЫЙ ЧАР ВАРЬИНГ (н)
NCHAR VARYING (n)
NVARCHAR2 (п)
ЧИСЛОВОЙ [(P, S)]
DECIMAL [(p, s)] (примечание 1)
НОМЕР (р, с)
INTEGER
INT
SMALLINT
НОМЕР (р, 0)
FLOAT (примечание 2)
ДВОЙНАЯ ТОЧНОСТЬ (Примечание 3)
РЕАЛЬНО (Примечание 4)
ПОПЛАВКОВЫЕ (126)
ПОПЛАВКОВЫЕ (126)
ПОПЛАВКОВЫЙ (63)

Типы, предоставляемые Oracle

Oracle предоставляет некоторые новые типы данных, которых нет во встроенных или поддерживаемых ANSI типах. Эти типы могут быть реализованы в C / C ++, Java или PL / SQL. Вот подробности:

Любые типы:
Типы Any обеспечивают очень гибкое моделирование параметров процедуры и столбцов таблицы, где фактический тип неизвестен. Эти типы данных позволяют динамически инкапсулировать и получать доступ к описаниям типов, экземплярам данных и наборам экземпляров данных любого другого типа SQL. Эти типы имеют интерфейсы OCI и PL / SQL для создания и доступа.

Типы XML:
Этот тип, предоставляемый Oracle, можно использовать для хранения и запроса данных XML в базе данных. XMLType имеет функции-члены, которые вы можете использовать для доступа, извлечения и запроса данных XML с использованием выражений XPath. XMLType является системным типом, поэтому вы можете использовать его как аргумент функции или как тип данных таблицы или столбца представления. Вы также можете создавать таблицы и представления XMLType. Когда вы создаете столбец XMLType в таблице, вы можете сохранить данные XML в столбце CLOB, как двоичный XML (хранящийся внутри как CLOB), или как объект реляционного типа.

Типы данных URI

Пространственные типы

Oracle Spatial разработан, чтобы сделать управление пространственными данными более простым и естественным для пользователей приложений с поддержкой определения местоположения, приложений геоинформационных систем (ГИС) и приложений геоизображения. После того, как пространственные данные сохранены в базе данных Oracle, вы можете легко манипулировать ими, извлекать и связывать их со всеми другими данными, хранящимися в базе данных. Следующие типы данных доступны, только если вы установили Oracle Spatial.

Тип данных Описание
SDO_GEOMETRY Геометрическое описание пространственного объекта хранится в одной строке, в одном столбце типа объекта SDO_GEOMETRY в пользовательской таблице. Любая таблица, имеющая столбец типа SDO_GEOMETRY, должна иметь другой столбец или набор столбцов, определяющих уникальный первичный ключ для этой таблицы. Таблицы такого рода иногда называют таблицами геометрии.
SDO_TOPO_GEOMETRY Этот тип описывает геометрию топологии, которая хранится в одной строке в одном столбце типа объекта SDO_TOPO_GEOMETRY в пользовательской таблице.
SDO_GEORASTER В объектно-реляционной модели GeoRaster растровая сетка или объект изображения хранятся в одной строке в одном столбце типа объекта SDO_GEORASTER в пользовательской таблице. Таблицы такого типа называются таблицами GeoRaster.

Типы СМИ

Oracle Multimedia использует типы объектов, подобные классам Java или C ++, для описания мультимедийных данных. Экземпляр этих типов объектов состоит из атрибутов, включая метаданные и медиаданные, а также методов. Мультимедийные типы данных создаются в схеме ORDSYS. Публичные синонимы существуют для всех типов данных, поэтому вы можете получить к ним доступ без указания имени схемы.
Oracle Multimedia предоставляет следующие типы объектов:

Тип данных Описание
ORDAudio Поддерживает хранение и управление аудиоданными.
ORDDicom Поддерживает хранение и управление цифровыми изображениями и коммуникациями в медицине (DICOM), формат, общепризнанный в качестве стандарта для медицинских изображений.
ORDDoc Поддерживает хранение и управление медиа-данными любого типа, включая аудио, изображения и видео. Используйте этот тип, если вы хотите, чтобы все мультимедиа хранились в одном столбце.
ORDImage Поддерживает хранение и управление данными изображения.
ORDVideo Поддерживает хранение и управление видеоданными.
ORDImageSignature Тип объекта ORDImageSignature устарел и больше не должен вводиться в ваш код. Существующие вхождения этого типа объекта будут продолжать функционировать как в прошлом.

Тип объекта ORDImageSignature устарел и больше не должен вводиться в ваш код. Существующие вхождения этого типа объекта будут продолжать функционировать как в прошлом.

Предыдущая: Oracle Home
Далее: Литералы

Ассоциативные массивы могут быть определены только в рамках программы PL/SQL
Ни структура массива, ни данные не могут сохраняться в БД.

Каждый элемент массива отличается индексом:

Индексирование с помощью binary_integer:


Индексирование с помощью varchar2:

Они впервые появились в Oracle 7 и назывались по разному:

Oracle 7 - таблицы PL/SQL
Oracle 8 - индекс таблицы
Oracle 10 - ассоциативные массивы

Объявляются они так:

type name is table of type [not null]
index by type;

Тип индекса может быть:

- binary_integer
- pls_integer
- positive
- natural
- signtype
- varchar2

Тип данных элемента может быть:
- number и его подтипы
- varchar2 и его подтипы
- date
- blob
- clob
- boolean

- типы данных наследуемые из столбца таблицы
- курсорного выражения
- предопределённой переменной модуля
- определённый пользователем тип объекта или коллекции

type clob_t is table of clob
index by pls_integer;

type empno_t is table of employees.empno%type not null
index by employees.ename%type;


Пример ассоциативного массива:

type ln is table pers.f_name%TYPE
index by pls_integer;

fam(20) := 'Tom';
fam(15) := 'Larry';
fam(-10) := 'Scott';

l_row := fam.FIRST;
while (l_row is not null) loop
dbms_output.put_line(fam(l_row));
l_row := fam.NEXT(l_row);
end loop;

set serveroutput on

type str_t is table of number
index by varchar2(10);

l_str str_t;
l_idx varchar2(50);

l_str('JAN-MAR') := 90;
l_str('APR-JUN') := 91;
l_str('JUL-SEP') := 92;
l_str('OCT-DEC') := 93;

l_idx := l_str.FIRST;
while (l_idx is not null) loop
dbms_output.put_line('Value at index ' || l_idx || 'is' || l_str(l_idx));
l_idx := l_str.NEXT(l_idx);
end loop;
end;
/


Следующий PL/SQL блок объявляет ассоциативный массив для хранения ASCII значений чисел от 1 до 100:

set serveroutput on

type ascii_t is table of varchar2(12)
index by pls_integer;

for i in 1 .. 100 loop
l_get_ascii(i) := ascii(i);
end loop;

Ассоциативные массивы :

- не могут быть использованы в таблицах и применяются только как программные структуры
- не требуют инициализации (нет метода EXTEND)
- индексы: только строки и числа
(положительные, отрицательные и нуль)

- неявно конвертируются из:
%ROWTYPE
типов записи
объектных типов
- не могут применяться в транзакциях DML (как непостоянные коллекции)
- могут передаваться как аргумент другим локальным подпрограммам в рамках одного и того-же блока.
- ассоциативный массив, объявленный в спецификации модуля, ведет себя как массив, постоянный внутри сессии.
в структуры ассоциативных массивов

- являются ключом к использованию оператора FORALL
или фразы BULK COLLECT
которые разрешают групповую пересылку данных из БД в программный модуль.

Если в качестве индекса используется индексная строка, то порядок их обработки
зависит от параметров БД:
NLS_SORT
NLS_COMP

type card is table of varchar2(5 char)
index by binary_integer;

-- конструктор использовать нельзя
cards card := card('A', 'B', 'C');
-- error 00222

-- объявим переменную
cards card;

-- нельзя перемещаться по ассоциативному массиву,
-- пока в нём отсутствуют элементы
dbms_output.put_line(cards(1));
-- error no data found


Чтобы избежать подобной ошибки делайте так:

type card is table of varchar2(5 char)
index by binary_integer;

if cards.COUNT < > 0 then
dbms_output.put_line(cards(1));
else
dbms_output.put_line('cards coll is empty.');
end if;


Метод COUNT возвращает нулевое значение только:
- когда у ассоциативного массива отсутствуют элементы с присиоенными значениями.
- когда varray или nested table проинициализпрованы и их элементам не выделена память

Метод EXTEND не сможет выделить память для ассоциированного массива

type card is table of varchar2(5 char)
index by binary_integer;

if cards.COUNT < > 0 then
dbms_output.put_line(cards(1));
else
cards.EXTEND;
-- error 00306
end if;

Инициализация ассоциативных массивов

type mv is varray(12) of varchar2(9 char);

type calt is table of varchar2(9 char)
index by binary_integer;

month mv := mv('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');

-- тут month - это varray
-- calendar - это ассоциативный массив

BEGIN
if calendar.COUNT = 0 then
dbms_output.put_line('Assigment loop:');
dbms_output.put_line('---------------');
for i in month.FIRST .. month.LAST LOOP
calendar(i):= '';
-- инициализируем
dbms_output.put_line('Index[' || i || '] is [' calendar(i) || ']');
calendar(i) := month(i);
end loop;

dbms_output.put_line(chr(10));
dbms_output.put_line('Post-assigment loop:');
dbms_output.put_line('--------------------');

for i in calendar.FIRST .. calendar.LAST LOOP
dbms_output.put_line('Index[' || i || '] is [' calendar(i) || ']');
end loop;
end if;


Числовой индекс:

type mv is varray(12) of string(9 char);

type calt is table of varchar2(9 char)
index by binary_integer;

month mv := mv('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');

calendar(1) := '';
calendar(1) := month(1);

Строковый индекс:

type mv is varray(12) of string(9 char);

type calt is table of varchar2(9 char)
index by varchar2(9 char);

month mv := mv('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');

calendar(January) := '1';
.
calendar(December) := '12';


calendar(April) - > 4
.
calendar(September) - > 9


Для строкового индекса процесс изменяется:

-- Присвоим значения:
if calendar.COUNT = 0 then
for i in month.FIRST .. month.LAST LOOP
calendar(month(i)):= i;
end loop;


-- Вывод значений:
for i in calendar.FIRST .. calendar.LAST LOOP
dbms_output.put_line('Index[' || i || '] is [' calendar(i) || ']');
end loop;
end if;

Инициализация сработает
А второй цикл for при выводе значений выдаст ошибку

calendar(April) - > 4
.
calendar(September) - > 9


При попытке вызвать функции FIRST и LAST мы получим ORA-06502
Ошибка преобразования числа

Тут происходит попытка передать нечисловое значениеиндекса в переменную счетчика.
Значение индекса в виде строки переменной длины не может быть приведено к целому числу,
т.к. оно не является целым числом.

Для нечисловых значений индексов необходимо знать с чего следует начинать и как наращивать.

Методы FIRST и NEXT дают нам такое средство

Рассмотрим логику обхода уникальных строковых индексов.

Определим две переменные, которые будут использованы для управления навигацией
по ассоциативному массиву с уникальными строковыми индексами

current varchar2(9 char);
element integer;

Цикл по всем элементам фссоциативного массива:

for i in 1 .. calendar.COUNT loop

-- проверьте, является ли элемент первым в списке
if i = 1 then
-- присвойте первый символьный индекс переменной
current := calendar.FIRST;

-- используйте полученный индекс для нахождения следующего индекса
element := calendar(current);
else
-- проверьте существует ли следующее значение индекса
if calendar.NEXT(current) is not null then

-- присвойте символьный индекс переменной
current := calendar.NEXT(current);

-- используйте полученный индекс для нахождения следующего индекса
element := calendar(current);
else
exit
-- было прочитано последнее значение индекса
end if
else if

dbms_output.put_line('Index[' || current || '] is [' element || ']');

Метод FORALL

Есть таблица t1 с полем id типа number.

Обычная вставка данных:

for i in 1 .. 10000 loop
insert into t1 values(i);
end loop;
commit;
end;
/

Вставка данных из коллекции:

forall i in 1 .. num_list.COUNT
insert into t1 values(num_list(i));
commit;
end;
/

Метод FORALL позволяет посылать операторы DML пакетами

Метод FORALL предлагает средство для переноса содержимого ассоциативного массива
или вложенной таблицы в объект БД.

type td is table of t1.id%type
index by binary_integer;

for i in 1 .. 10000 loop
insert into t1 values(i);
end loop;


forall i in 1 .. num_list.COUNT
insert into t1 values(num_list(i));
commit;
-- фиксируем результат каждого пакета вставок
end;
/


Метод BULK COLLECT

Метод BULK COLLECT позволяет выбирать наборы записей ,
которые можно хранить в массивах переменной длины и во вложенных таблицах.

Метод BULK COLLECT позволяет, как единое множество,
присвоить коллекцию значений %ROWTYPE или %TYPE ассоциативному массиву
или вложенной таблице.

Вложенную таблицу необходимо построить как коллекцию пустых элементов.

Память во вложенной таблице будет неявно выделять bulk collect

Для ассоциированного массива не требуется конструктора,
достаточно группового присваивания.

Читайте также: