Пользовательская установка верхней и нижней границы может быть явно определена для каждой размерности массива при создании столбца ARRAY. Например, программисты С и Pascal, знакомые с массивами, основанными на нуле, могут создавать столбцы массивов с нулевой нижней границей для полного соответствия со структурой массивов в коде приложения.
Требуются нижняя и верхняя граница размерности при определении пользовательских границ. Используется следующий синтаксис:
[ нижняя:верхняя]
Следующий пример создает таблицу с одноразмерным, основанным на нуле столбцом массива:
CREATE TABLE TABLED
(ARR_INT INTEGER[0:3]);
/* индексы 0, 1, 2, и 3. */
Каждое задание границ размерности отделяется от следующего запятой. Например, следующий оператор создает таблицу со столбцом массива размерности два, где обе размерности основаны на нуле:
CREATE TABLE TABLEE
(ARR_INT INTEGER[0:3, 0:3]);
Хранение столбцов массивов
Как и другие типы данных, реализованные как BLOB, Firebird хранит идентификатор массива в столбце таблицы базы данных, который ссылается на страницу, содержащую фактические данные.
Как и в случае других типов BLOB, сервер Firebird не может последовательно просматривать индивидуальные элементы при условном обновлении. При этом в одиночном операторе DML возможно изолировать один элемент или набор последовательных элементов, называемый фрагментом, и передавать этот фрагмент для обновления.
Оператор INSERT не может оперировать с фрагментами. Когда строка добавляется в таблицу, содержащую столбцы массивов, необходимо конструировать и заполнять массив целиком до передачи его INSERT.
Доступ к данным массива
Некоторые интерфейсы приложений инкапсулируют функции и дескрипторы API, ограниченный доступ для чтения возможен из хранимых процедур.
API предоставляет структуру дескриптора массива для передачи серверу массива или фрагмента массива для чтения и записи в базу данных. Эта структура для программистов представлена в файле ibase.h (добавлены комментарии):
typedef struct {
short array_bound_lower;
/* нижняя граница массива или фрагмента */
short array_bound_upper;
/* верхняя граница массива или фрагмента */
} | SC_ARRAY_BOUND;
typedef struct {
unsigned char array_desc_dtype;
/* тип данных элементов */
char array_desc_scale;
/* масштаб для числовых типов */
unsigned short array_desc_length;
/* длина элемента массива в байтах */
char array_desc_field_name[32] ;
/* идентификатор столбца */
char array_desc_relation_name[32];
/* идентификатор таблицы */
short array_desc_dimensions;
/* количество размерностей */
short array_desc_flags;
/* 0=порядок по строкам, 1=порядок по столбцам */
ISC_ARRAY_BOUND array_desc_bounds[16];
/* верхняя и нижняя границы для размерности до 16 */
} ISC_ARRAY_DE SC;
Документ по InterBase 6 "API Guide" (Руководство no API), опубликованный Borland, содержит детальные инструкции по манипулированию массивами с помощью структур API.
Ограничения доступа динамического SQL
Следующий пример является простой демонстрацией того, как приложение DSQL может получить ограниченный доступ к фрагменту массива через хранимую процедуру:
create procedure getcharslice(
low_elem smallint, high_elem smallint)
returns (id integer, list varchar(50))
as
declare variable i smallint;
declare variable string varchar(10);
begin
for select a1.ID from ARRAYS a1 into :id do
begin
i= low_elem;
list = '' ;
while (i <= high_elem) do
begin
select a2.CHARARRAY[:i] from arrays a2
where a2.ID = :id
into : string;
list = list||string;
if (i < high_elem) then
list = list ||',';
i = i + 1;
end
suspend;
end
end
Последняя глава этой части книги описывает, как объединить тип данных и его дополнительные атрибуты в домен, который вы можете использовать для определения типов данных в столбцах различных таблиц.
ГЛАВА 13. Домены.
Домены в Firebird сродни концепции "типы данных, определенные пользователем". Хотя и невозможно создать новый тип данных, в домене вы можете "упаковать" набор атрибутов с одним из существующих типов данных, присвоить ему идентификатор и после этого использовать его как параметр типа данных для определения столбцов любой таблицы.
Определения доменов являются глобальными для базы данных - все столбцы в любой таблице, которые были определены с одним доменом, будут иметь совершенно идентичные атрибуты за исключением тех, которые были локально переопределены.
Как было отмечено, домены не могут быть подставлены вместо типов данных при определении аргументов и переменных в хранимых процедурах и триггерах.
! ! !
ПРИМЕЧАНИЕ. Замещение атрибутов домена на уровне столбца обсуждается позже в этой главе.
. ! .
Столбцы, основанные на определении домена, наследуют все атрибуты домена, которые могут быть:
* типом данных (обязательно);
* значением по умолчанию для INSERT;
* состоянием NULL;
* ограничениями CHECK;
* набором символов (только для символьных и BLOB столбцов);
* порядком сортировки (только для символьных столбцов).
! ! !