FirebirdSQL logo
 DOMAININDEX 

Глобальные временные таблицы (GTT)

Глобальные временные таблицы (в дальнейшем сокращённо “GTT”) так же, как и обычные таблицы, являются постоянными метаданными, но данные в них ограничены по времени существования транзакцией (значение по умолчанию) или соединением с БД.Каждая транзакция или соединение имеет свой собственный экземпляр GTT с данными, изолированный от всех остальных.Экземпляры создаются только при условии обращения к GTT, и данные в ней удаляются при завершении транзакции или отключении от БД.Метаданные GTT могут быть изменены или удалены с помощью инструкций ALTER TABLE и DROP TABLE.

Синтаксис
CREATE GLOBAL TEMPORARY TABLE name
  (<column_def> [, {<column_def> | <table_constraint>} ...])
  [ON COMMIT {DELETE | PRESERVE} ROWS]
  [SQL SECURITY {DEFINER | INVOKER}]

Если в операторе создания глобальной временной таблицы указано необязательное предложение ON COMMIT DELETE ROWS, то будет создана GTT транзакционного уровня (по умолчанию). При указании предложения ON COMMIT PRESERVE ROWS — будет создана GTT уровня соединения с базой данных.

Предложение EXTERNAL [FILE] нельзя использовать для глобальной временной таблицы.

Note

Операторы COMMIT RETAINING и ROLLBACK RETAINING сохраняют данные в глобальных временных таблицах объявленных как ON COMMIT DELETE ROWS.В Firebird 2.x была ошибка: COMMIT RETAINING и ROLLBACK RETAINING делали записи не видимыми для текущей транзакции.Для возврата поведения 2.x установить параметр ClearGTTAtRetaining равным 1 в firebird.conf.Этот параметр может быть удалён в Firebird 5.0.

Ограничения GTT

GTT обладают всеми атрибутами обычных таблиц (ключи, внешние ключи, индексы и триггеры), но имеют ряд ограничений:

  • GTT и обычные таблицы не могут ссылаться друг на друга;

  • GTT уровня соединения (“PRESERVE ROWS”) GTT не могут ссылаться на GTT транзакционного уровня (“DELETE ROWS”);

  • Ограничения домена не могут ссылаться на любую GTT;

  • Уничтожения экземпляра GTT в конце своего жизненного цикла не вызывает срабатывания триггеров до/после удаления.

Tip

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

SELECT t.rdb$type_name
FROM rdb$relations r
JOIN rdb$types t ON r.rdb$relation_type = t.rdb$type
WHERE t.rdb$field_name = 'RDB$RELATION_TYPE'
  AND r.rdb$relation_name = 'TABLENAME'

Для просмотра информации о типах всех таблиц используйте запрос:

SELECT r.rdb$relation_name, t.rdb$type_name
FROM rdb$relations r
JOIN rdb$types t ON r.rdb$relation_type = t.rdb$type
WHERE t.rdb$field_name = 'RDB$RELATION_TYPE'
  AND coalesce (r.rdb$system_flag, 0) = 0

Поле RDB$TYPE_NAME будет отображать PERSISTENT для обычной таблицы, VIEW для представления, GLOBAL_TEMPORARY_PRESERVE для GTT уровня соединения, и GLOBAL_TEMPORARY_DELETE для GTT уровня транзакции.

Примеры

Example 1. Создание глобальной временной таблицы уровня соединения
CREATE GLOBAL TEMPORARY TABLE MYCONNGTT (
    ID INTEGER NOT NULL PRIMARY KEY,
    TXT VARCHAR(32),
    TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
ON COMMIT PRESERVE ROWS;
Example 2. Создание глобальной временной таблицы уровня транзакции ссылающейся внешним ключом на глобальную временную таблицу уровня соединения.
CREATE GLOBAL TEMPORARY TABLE MYTXGTT (
    ID INTEGER NOT NULL PRIMARY KEY,
    PARENT_ID INTEGER NOT NULL REFERENCES MYCONNGTT(ID),
    TXT VARCHAR(32),
    TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP);