FirebirdSQL logo
 DOMAININDEX 

Внешние таблицы

Необязательное предложение EXTERNAL [FILE] указывает, что таблица хранится вне базы данных во внешнем текстовом файле.Столбцы таблицы, хранящейся во внешнем файле, могут быть любого типа за исключением BLOB и массивов с любым типом данных.

Над таблицей, хранящейся во внешнем файле, допустимы только операции добавления новых строк (INSERT) и выборки (SELECT) данных.Операции же изменения существующих данных (UPDATE) или удаления строк такой таблицы (DELETE) не могут быть выполнены.

Внешняя таблица не может содержать ограничений первичного, внешнего и уникального ключа.Для полей такой таблицы невозможно создать индексы.

Файл с внешней таблицей должен располагаться на устройстве хранения, физически расположенном на сервере, на котором расположена СУБД.Если параметр ExternalFileAccess в файле конфигурации firebird.conf содержит Restrict, то файл внешней таблицы должен находится в одном из каталогов, указанных в качестве аргумента Restrict.Если при обращении к таблице Firebird не находит файла, то он создаёт его при первом обращении.

Important

Возможность использования для таблиц внешних файлов зависит от установки значения параметра ExternalFileAccess в файле конфигурации firebird.conf:

  • Если он установлен в значение None, то запрещён любой доступ к внешнему файлу.

  • Значение Restrict рекомендуется для ограничения доступа к внешним файлам только каталогами, созданными специально для этой цели администратором сервера. Например:

    • ExternalFileAccess = Restrict externalfiles ограничит доступ директорией externalfiles корневого каталога Firebird.

    • ExternalFileAccess = Restrict d:\databases\outfiles; e:\infiles ограничит доступ только двумя директориями Windows. Обратите внимание, что любые пути являющиеся отображением сетевых путей не будут работать. Также не будут работать пути заключённые в одинарные или двойные кавычки.

  • Значение Full позволяет доступ к внешним файлам в любом месте файловой системы хоста. Это создаёт уязвимость и не рекомендуется к использованию.

Формат внешних файлов

Внешняя таблица имеет формат “строк” с фиксированной длинной.Нет никаких разделителей полей: границы полей и строк определяются максимальными размерами в байтах в определении каждого поля.Это необходимо помнить и при определении структуры внешней таблицы, и при проектировании входного файла для внешней таблицы, в которую должны импортироваться данные из другого приложения.Например, широко распространённый формат “.csv”, не может быть использован в качестве входного файла, и не может быть получен непосредственно как внешний файл.

Самым полезным типом данных для столбцов внешних таблиц является тип CHAR с фиксированной длинной, длинна должна подходить под данные с которыми необходимо работать.Числовые типы и даты легко преобразуются в них, строки получаются как есть, в то время как, если данные не читаются другой базой данных Firebird, то родные типы могут быть нераспознаваемыми дня внешних приложений и являться для них “абракадаброй”.

Конечно, существуют способы манипулирования типами данных так, чтобы создавать выходные файлы из Firebird, которые могут быть непосредственно прочитаны как входные файлы в других приложениях, используя хранимые процедуры с использованием внешних таблиц или без них.Описания этих методов выходит за рамки данного руководства.Здесь мы приведём лишь некоторые рекомендации и советы для создания и работы с простыми текстовыми файлами, поскольку внешняя таблица часто используется как простой способ для создания или чтения транзакционно-независимого журнала.Эти файлы могут быть прочитаны в оффлайн режиме текстовым редактором или приложением аудита.

Разделитель строк

Как правило, внешние файлы более удобны если строки разделены разделителем, в виде последовательности "новой строки", которая может быть распознана приложением на предназначенной платформе.Для Windows — это двухбайтная 'CRLF' последовательность, возврат каретки (ASCII код 13) и перевод строки (ASCII код 10).Для POSIX — LF обычно самодостаточен, в некоторых MacOS X приложениях она может быть LFCR.Существуют различные способы для автоматического заполнения столбца разделителя.В нашем примере это сделано с помощью BEFORE INSERT триггера и встроенной функции ASCII_CHAR.

Примеры использования внешних таблиц

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

CREATE TABLE ext_log
EXTERNAL FILE 'd:\externals\log_me.txt' (
   stamp   CHAR(24),
   message CHAR(100),
   crlf    CHAR(2) -- Для Windows
);

COMMIT;

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

SET TERM ^;
CREATE TRIGGER bi_ext_log FOR ext_log
ACTIVE BEFORE INSERT
AS
BEGIN
  IF (NEW.stamp IS NULL) THEN
    NEW.stamp = CAST (CURRENT_TIMESTAMP AS CHAR(24));
  NEW.crlf = ASCII_CHAR(13) || ASCII_CHAR(10);
END ^
COMMIT ^
SET TERM ;^

Вставка некоторых записей (это может быть сделано в обработчике исключения):

INSERT INTO ext_log (message)
VALUES('Shall I compare thee to a summer''s day?');
INSERT INTO ext_log (message)
VALUES('Thou art more lovely and more temperate');

Содержимое внешнего файла:

2015-10-07 15:19:03.4110Shall I compare thee to a summer's day?
2015-10-07 15:19:58.7600Thou art more lovely and more temperate
См. также:

ALTER TABLE, DROP TABLE, CREATE DOMAIN.