32. Системные пакеты

32.1. RDB$TIME_ZONE_UTIL

Пакет RDB$TIME_ZONE_UTIL содержит процедуру TRANSITIONS и функцию DATABASE_VERSION для работы с часовыми поясами.

Функция DATABASE_VERSION

Функция RDB$TIME_ZONE_UTIL.DATABASE_VERSION возвращает версию базы данных часовых поясов (из библиотеки icu) типа VARCHAR(10) CHARACTER SET ASCII.

SELECT rdb$time_zone_util.database_version()
FROM rdb$database;

DATABASE_VERSION
================
2024a

Процедура TRANSITIONS

Процедура RDB$TIME_ZONE_UTIL.TRANSITIONS возвращает набор правил для часового пояса между начальной и конечной временной меткой.

Таблица 32.1 Входные параметры процедуры TRANSITIONS

Параметр

Тип

Описание

RDB$TIME_ZONE_NAME

CHAR(63)

Наименование часового пояса

RDB$FROM_TIMESTAMP

TIMESTAMP WITH TIME ZONE

Начало интервала дат

RDB$TO_TIMESTAMP

TIMESTAMP WITH TIME ZONE

Окончание интервала дат

Таблица 32.2 Выходные параметры процедуры TRANSITIONS

Параметр

Тип

Описание

RDB$START_TIMESTAMP

TIMESTAMP WITH TIME ZONE

Дата начала действия правила

RDB$END_TIMESTAMP

TIMESTAMP WITH TIME ZONE

Дата окончания действия правила

RDB$ZONE_OFFSET

SMALLINT

Смещение времени в минутах для заданного часового пояса

RDB$DST_OFFSET

SMALLINT

Летннее смещение времени в минутах для заданного часового пояса

RDB$EFFECTIVE_OFFSET

SMALLINT

Эффективное смещение, вычисляется как RDB$ZONE_OFFSET + RDB$DST_OFFSET

SELECT
   RDB$START_TIMESTAMP AS START_TIMESTAMP,
   RDB$END_TIMESTAMP AS END_TIMESTAMP,
   RDB$ZONE_OFFSET AS ZONE_OFF,
   RDB$DST_OFFSET AS DST_OFF,
   RDB$EFFECTIVE_OFFSET AS OFF
FROM rdb$time_zone_util.transitions('America/Sao_Paulo' ,
                                     timestamp '2017-01-01' ,
                                     timestamp '2019-01-01' );

START_TIMESTAMP               END_TIMESTAMP                 ZONE_OFF  DST_OFF  OFF
============================  ============================  ========  =======  ====
2016-10-16 03:00:00.0000 GMT  2017-02-19 01:59:59.9999 GMT  -180      60       -120
2017-02-19 02:00:00.0000 GMT  2017-10-15 02:59:59.9999 GMT  -180      0        -180
2017-10-15 03:00:00.0000 GMT  2018-02-18 01:59:59.9999 GMT  -180      60       -120
2018-02-18 02:00:00.0000 GMT  2018-11-04 02:59:59.9999 GMT  -180      0        -180
2018-11-04 03:00:00.0000 GMT  2019-02-17 01:59:59.9999 GMT  -180      60       -120

32.2. RDB$BLOB_UTIL

Пакет RDB$BLOB_UTIL предназначен для обработки данных BLOB напрямую, чего не могут делать стандартные функции, такие как BLOB_APPEND и SUBSTRING.

Функция NEW_BLOB

Функция NEW_BLOB используется для создания нового BLOB. Она возвращает BLOB, предназначенный для добавления данных, как BLOB_APPEND. Преимущество перед BLOB_APPEND заключается в том, что можно задать опции SEGMENTED и TEMP_STORAGE. BLOB_APPEND всегда создает BLOB во временном хранилище, что может быть не лучшим подходом, если созданный BLOB будет храниться в постоянной таблице, поскольку потребуется копирование. BLOB, возвращаемый функцией NEW_BLOB, даже если TEMP_STORAGE = FALSE, может использоваться с BLOB_APPEND для добавления данных.

Таблица 32.3 Входные параметры функции NEW_BLOB

Параметр

Тип

Описание

SEGMENTED

BOOLEAN NOT NULL

Тип BLOB: true - сегментированный, false - потоковый

TEMP_STORAGE

BOOLEAN NOT NULL

Место хранения BLOB: true - во временном пространстве, false - в базе данных

Пример создания BLOB во временном пространстве и возвращение его в EXECUTE BLOCK:

execute block returns (b blob)
as
begin
   -- Создание дескриптора BLOB во временном пространстве.
   b = rdb$blob_util.new_blob(false, true);

   -- Добавление фрагментов данных.
   b = blob_append(b, '12345');
   b = blob_append(b, '67');
   suspend;
end!

Функция OPEN_BLOB

Функция OPEN_BLOB используется для открытия существующего BLOB для чтения. Она возвращает дескриптор (целое число, связанное с транзакцией), подходящий для использования с другими функциями этого пакета, такими как SEEK, READ_DATA и CLOSE_HANDLE.

Таблица 32.4 Входные параметры функции OPEN_BLOB

Параметр

Тип

Описание

BLOB

BLOB NOT NULL

Переменная типа BLOB

Функция IS_WRITABLE

Функция IS_WRITABLE возвращает true, если BLOB подходит для добавления данных без копирования с помощью BLOB_APPEND.

Таблица 32.5 Входные параметры функции IS_WRITABLE

Параметр

Тип

Описание

BLOB

BLOB NOT NULL

Переменная типа BLOB

Пример проверки BLOB на доступность для записи:

create table t(b blob);

set term !;

execute block returns (bool boolean)
as
  declare b blob;
begin
  b = blob_append(null, 'writable');
  bool = rdb$blob_util.is_writable(b);
  suspend;

  insert into t (b) values ('not writable') returning b into b;
  bool = rdb$blob_util.is_writable(b);
  suspend;
end!

set term ;!

Функция READ_DATA

Функция READ_DATA используется для чтения фрагментов данных по дескриптору BLOB, открытому с помощью RDB$BLOB_UTIL.OPEN_BLOB. Возвращает NULL, когда BLOB полностью прочитан. Если LENGTH передается с положительным числом, он возвращает VARBINARY с его максимальной длиной. Если LENGTH равна NULL, то возвращается только сегмент BLOB с максимальной длиной 32765.

Таблица 32.6 Входные параметры функции READ_DATA

Параметр

Тип

Описание

HANDLE

INTEGER NOT NULL

Дескриптор

LENGTH

INTEGER

Длина

Пример открытия BLOB и возвращения его частей с помощью EXECUTE BLOCK:

execute block returns (s varchar(10))
as
   declare b blob = '1234567';
   declare bhandle integer;
begin
   -- Открытие BLOB и получение дескриптора BLOB.
   bhandle = rdb$blob_util.open_blob(b);

   -- Получение и возвращение фрагментов данных в виде строки.
   s = rdb$blob_util.read_data(bhandle, 3);
   suspend;

   s = rdb$blob_util.read_data(bhandle, 3);
   suspend;

   s = rdb$blob_util.read_data(bhandle, 3);
   suspend;

   -- Здесь BLOB полностью прочитан, поэтому возвращается NULL.
   s = rdb$blob_util.read_data(bhandle, 3);
   suspend;

   -- Закрытие дескриптора BLOB.
   execute procedure rdb$blob_util.close_handle(bhandle);
end!

Функция SEEK

Функция SEEK возвращает новую позицию для следующего READ_DATA. MODE может быть 0 (c начала), 1 (c текущей позиции) или 2 (c конца). Если MODE равен 2, OFFSET должен быть нулевым или отрицательным.

Таблица 32.7 Входные параметры функции SEEK

Параметр

Тип

Описание

HANDLE

INTEGER NOT NULL

Дескриптор

MODE

INTEGER NOT NULL

Режим

OFFSET

INTEGER NOT NULL

Смещение

Пример работы функции SEEK:

set term !;

execute block returns (s varchar(10))
as
   declare b blob;
   declare bhandle integer;
begin
   -- Создание дескриптора потокового BLOB
   b = rdb$blob_util.new_blob(false, true);

   -- Добавление данных.;
   b = blob_append(b, '0123456789');

   -- Открытие BLOB.;
   bhandle = rdb$blob_util.open_blob(b);

   -- Поиск с начала до 5.;

   rdb$blob_util.seek(bhandle, 0, 5);
   s = rdb$blob_util.read_data(bhandle, 3);
   suspend;

   -- Поиск с начала до 2.
   rdb$blob_util.seek(bhandle, 0, 2);
   s = rdb$blob_util.read_data(bhandle, 3);
   suspend;

  -- Ещё на 2 вперед.
  rdb$blob_util.seek(bhandle, 1, 2);
  s = rdb$blob_util.read_data(bhandle, 3);
  suspend;

  -- Поиск с конца на один элемент назад.
  rdb$blob_util.seek(bhandle, 2, -1);
  s = rdb$blob_util.read_data(bhandle, 3);
  suspend;
end!
set term ;!

Процедура CANCEL_BLOB

Процедура CANCEL_BLOB используется для немедленного освобождения временного BLOB, например, созданного с помощью BLOB_APPEND.

Предупреждение

Обратите внимание, что если тот же BLOB будет использован после отмены, используя ту же переменную или другую переменную с той же ссылкой на BLOB id, будет выдана ошибка invalid blob id.

Процедура CLOSE_HANDLE

Процедура CLOSE_HANDLE используется для закрытия дескриптора BLOB, открытого с помощью OPEN_BLOB. Незакрытые дескрипторы закрываются автоматически только в конце транзакции.

Таблица 32.8 Входные параметры процедуры CLOSE_HANDLE

Параметр

Тип

Описание

HANDLE

INTEGER NOT NULL

Дескриптор