×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

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

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

6.1.91. CREATE TRIGGER

6.1.91. CREATE TRIGGER

CREATE TRIGGER — создание нового триггера

Синтаксис

CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] }
    ON table_name
    [ FROM referenced_table_name ]
    [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
    [ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ]
    [ FOR [ EACH ] { ROW | STATEMENT } ]
    [ WHEN ( condition ) ]
    EXECUTE { FUNCTION | PROCEDURE } function_name ( arguments )

где event может быть одним из:

    INSERT
    UPDATE [ OF column_name [, ... ] ]
    DELETE
    TRUNCATE

Описание

CREATE TRIGGER создаёт новый триггер. CREATE OR REPLACE TRIGGER либо создаст новый триггер, либо заменит существующий триггер. Триггер будет связан с указанной таблицей, представлением или внешней таблицей и будет выполнять указанную функцию function_name, когда над этой таблицей выполняются определённые операции.

Чтобы заменить текущее определение существующего триггера, используйте CREATE OR REPLACE TRIGGER, указав имя существующего триггера и родительскую таблицу. Все остальные свойства заменяются.

Триггер можно указать для срабатывания до того, как операция будет предпринята над строкой (до проверки ограничений и попытки выполнения INSERT, UPDATE или DELETE); или после завершения операции (после проверки ограничений и завершения INSERT, UPDATE или DELETE); или вместо операции (в случае вставок, обновлений или удалений в представлении). Если триггер срабатывает до или вместо события, он может пропустить операцию для текущей строки или изменить вставляемую строку (только для операций INSERT и UPDATE). Если триггер срабатывает после события, все изменения, включая эффекты других триггеров, «видны» для этого триггера.

Триггер, помеченный как FOR EACH ROW, вызывается один раз для каждой строки, которую модифицирует операция. Например, команда DELETE, затрагивающая 10 строк, вызовет любые триггеры ON DELETE на целевом отношении 10 раз отдельно, один раз для каждой удалённой строки. В отличие от этого, триггер, помеченный как FOR EACH STATEMENT, выполняется только один раз для данной операции, независимо от того, сколько строк она модифицирует (в частности, операция, которая не модифицирует ни одной строки, всё равно приведёт к выполнению любых применимых триггеров FOR EACH STATEMENT).

Триггеры, указанные для срабатывания INSTEAD OF события, должны быть помечены как FOR EACH ROW и могут быть определены только на представлениях. Триггеры BEFORE и AFTER на представлении должны быть помечены как FOR EACH STATEMENT.

Кроме того, триггеры могут быть определены для срабатывания по команде TRUNCATE, хотя только как FOR EACH STATEMENT.

Следующая таблица суммирует, какие типы триггеров могут использоваться на таблицах, представлениях и внешних таблицах:

КогдаСобытиеПострочныйНа уровне оператора
BEFOREINSERT/UPDATE/DELETEТаблицы и внешние таблицыТаблицы, представления и внешние таблицы
TRUNCATEТаблицы и внешние таблицы
AFTERINSERT/UPDATE/DELETEТаблицы и внешние таблицыТаблицы, представления и внешние таблицы
TRUNCATEТаблицы и внешние таблицы
INSTEAD OFINSERT/UPDATE/DELETEПредставления
TRUNCATE

Кроме того, в определении триггера можно указать логическое условие WHEN, которое будет проверяться, чтобы определить, должен ли триггер сработать. В построчных триггерах условие WHEN может проверять старые и/или новые значения столбцов строки. Триггеры на уровне оператора также могут иметь условия WHEN, хотя эта возможность не так полезна для них, поскольку условие не может ссылаться на какие-либо значения в таблице.

Если для одного события определено несколько триггеров одного вида, они будут срабатывать в алфавитном порядке по имени.

При указании опции CONSTRAINT эта команда создаёт триггер ограничения (constraint trigger). Это то же самое, что обычный триггер, за исключением того, что время срабатывания триггера можно регулировать с помощью SET CONSTRAINTS. Триггеры ограничений должны быть триггерами AFTER ROW на обычных таблицах (не внешних таблицах). Они могут срабатывать либо в конце оператора, вызывающего событие, либо в конце содержащей транзакции; в последнем случае они называются отложенными (deferred). Ожидающее отложенное срабатывание триггера также может быть принудительно выполнено немедленно с помощью SET CONSTRAINTS. Ожидается, что триггеры ограничений вызывают исключение, когда нарушаются реализуемые ими ограничения.

Опция REFERENCING позволяет собирать переходные отношения (transition relations), то есть наборы строк, включающие все строки, вставленные, удалённые или изменённые текущим оператором SQL. Эта возможность позволяет триггеру видеть глобальное представление о том, что сделал оператор, а не только по одной строке за раз. Эта опция разрешена только для триггеров AFTER, которые не являются триггерами ограничений; также, если триггер является триггером UPDATE, он не должен указывать список column_name. OLD TABLE может быть указан только один раз и только для триггера, который может срабатывать по событиям UPDATE или DELETE; он создаёт переходное отношение, содержащее предыдущие образы (before-images) всех строк, обновлённых или удалённых оператором. Аналогично, NEW TABLE может быть указан только один раз и только для триггера, который может срабатывать по событиям UPDATE или INSERT; он создаёт переходное отношение, содержащее последующие образы (after-images) всех строк, обновлённых или вставленных оператором.

Команда SELECT не изменяет никакие строки, поэтому нельзя создавать триггеры на SELECT. Правила и представления могут предоставлять рабочие решения проблем, которые, кажется, требуют триггеров SELECT.

Дополнительную информацию о триггерах см. в Глава 5.2.

Параметры

name

Имя нового триггера. Оно должно отличаться от имени любого другого триггера для той же таблицы. Имя не может быть указано с квалификацией схемы — триггер наследует схему своей таблицы. Для триггера ограничения это также имя, которое используется при изменении поведения триггера с помощью SET CONSTRAINTS.

BEFORE
AFTER
INSTEAD OF

Определяет, вызывается ли функция до, после или вместо события. Триггер ограничения может быть указан только как AFTER.

event

Одно из значений: INSERT, UPDATE, DELETE или TRUNCATE; оно определяет событие, которое вызовет триггер. Несколько событий можно указать с помощью OR, за исключением случаев, когда запрашиваются переходные отношения.

Для событий UPDATE можно указать список столбцов, используя следующий синтаксис:

UPDATE OF column_name1 [, column_name2 ... ]

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

События INSTEAD OF UPDATE не допускают список столбцов. Список столбцов также не может быть указан при запросе переходных отношений.

table_name

Имя (возможно, с указанием схемы) таблицы, представления или внешней таблицы, для которой предназначен триггер.

referenced_table_name

Имя (возможно, с указанием схемы) другой таблицы, на которую ссылается ограничение. Этот параметр используется для ограничений внешнего ключа и не рекомендуется для общего использования. Он может быть указан только для триггеров ограничений.

DEFERRABLE
NOT DEFERRABLE
INITIALLY IMMEDIATE
INITIALLY DEFERRED

Время срабатывания триггера по умолчанию. Подробности об этих параметрах ограничений см. в документации CREATE TABLE. Это может быть указано только для триггеров ограничений.

REFERENCING

Это ключевое слово непосредственно предшествует объявлению одного или двух имён отношений, которые предоставляют доступ к переходным отношениям оператора, вызвавшего срабатывание.

OLD TABLE
NEW TABLE

Это предложение указывает, является ли следующее имя отношения именем для переходного отношения предыдущих образов (before-image) или последующих образов (after-image).

transition_relation_name

Имя (без квалификатора), которое будет использоваться внутри триггера для этого переходного отношения.

FOR EACH ROW
FOR EACH STATEMENT

Определяет, должна ли функция триггера срабатывать один раз для каждой строки, затронутой событием триггера, или только один раз за оператор SQL. Если ни одно не указано, по умолчанию используется FOR EACH STATEMENT. Триггеры ограничений могут быть указаны только как FOR EACH ROW.

condition

Логическое выражение, определяющее, будет ли функция триггера фактически выполнена. Если указано WHEN, функция будет вызвана только если condition возвращает true. В триггерах FOR EACH ROW условие WHEN может ссылаться на столбцы старых и/или новых значений строк, записывая OLD.column_name или NEW.column_name соответственно. Конечно, триггеры INSERT не могут ссылаться на OLD, а триггеры DELETE не могут ссылаться на NEW.

Триггеры INSTEAD OF не поддерживают условия WHEN.

В настоящее время выражения WHEN не могут содержать подзапросы.

Обратите внимание, что для триггеров ограничений оценка условия WHEN не откладывается, а происходит сразу после выполнения операции обновления строки. Если условие не вычисляется в true, то триггер не ставится в очередь на отложенное выполнение.

function_name

Предоставленная пользователем функция, объявленная как не принимающая аргументов и возвращающая тип trigger, которая выполняется при срабатывании триггера.

В синтаксисе CREATE TRIGGER ключевые слова FUNCTION и PROCEDURE эквивалентны, но упоминаемая функция в любом случае должна быть функцией, а не процедурой. Использование ключевого слова PROCEDURE здесь историческое и устарело.

arguments

Необязательный список аргументов, разделённых запятыми, который будет предоставлен функции при выполнении триггера. Аргументы являются строковыми константами. Простые имена и числовые константы также могут быть записаны здесь, но они все будут преобразованы в строки. Пожалуйста, проверьте описание языка реализации функции триггера, чтобы узнать, как эти аргументы могут быть доступны внутри функции; это может отличаться от обычных аргументов функции.

Примечания

Для создания или замены триггера на таблице пользователь должен иметь привилегию TRIGGER на этой таблице. Пользователь также должен иметь привилегию EXECUTE на функцию триггера.

Используйте DROP TRIGGER для удаления триггера.

Создание построчного триггера на секционированной таблице вызовет создание идентичного «клон»-триггера на каждой из её существующих секций; и любые секции, созданные или присоединённые позже, также будут иметь идентичный триггер. Если в дочерней секции уже существует триггер с конфликтующим именем, возникает ошибка, если только не используется CREATE OR REPLACE TRIGGER, и в этом случае этот триггер заменяется на клон-триггер. Когда секция отделяется от родительской, её клон-триггеры удаляются.

Триггер, специфичный для столбца (определённый с использованием синтаксиса UPDATE OF column_name), сработает, когда любой из его столбцов указан в качестве цели в списке SET команды UPDATE. Возможно изменение значения столбца даже тогда, когда триггер не срабатывает, потому что изменения, внесённые в содержимое строки триггерами BEFORE UPDATE, не учитываются. И наоборот, команда вида UPDATE ... SET x = x ... вызовет триггер на столбце x, даже если значение столбца не изменилось.

В триггере BEFORE условие WHEN вычисляется непосредственно перед тем, как функция будет или должна быть выполнена, поэтому использование WHEN не сильно отличается от проверки того же самого условия в начале функции триггера. Обратите внимание, в частности, что строка NEW, видимая условию, является текущим значением, возможно, изменённым предыдущими триггерами. Кроме того, условию WHEN триггера BEFORE не разрешается проверять системные столбцы строки NEW (такие как ctid), потому что они ещё не будут установлены.

В триггере AFTER условие WHEN вычисляется сразу после обновления строки и определяет, будет ли событие поставлено в очередь для срабатывания триггера в конце оператора. Поэтому когда условие WHEN триггера AFTER не возвращает true, не нужно ставить событие в очередь и повторно извлекать строку в конце оператора. Это может привести к значительному ускорению выполнения операторов, которые изменяют много строк, если триггер нужно срабатывать только для нескольких из этих строк.

В некоторых случаях возможно, чтобы одна команда SQL вызывала более чем один вид триггеров. Например, команда INSERT с предложением ON CONFLICT DO UPDATE может вызывать как операции вставки, так и обновления, поэтому при необходимости она вызовет оба вида триггеров. Переходные отношения, предоставляемые триггерам, специфичны для их типа события; таким образом, триггер INSERT увидит только вставленные строки, а триггер UPDATE увидит только обновлённые строки.

Обновления или удаления строк, вызванные действиями по обеспечению внешнего ключа, такими как ON UPDATE CASCADE или ON DELETE SET NULL, рассматриваются как часть команды SQL, которая их вызвала (обратите внимание, что такие действия никогда не откладываются). Соответствующие триггеры в затронутой таблице будут срабатывать, что предоставляет ещё один способ, которым команда SQL может вызывать триггеры, не соответствующие напрямую её типу. В простых случаях триггеры, которые запрашивают переходные отношения, увидят все изменения, вызванные в их таблице одной исходной командой SQL, как единое переходное отношение. Однако бывают случаи, когда наличие триггера AFTER ROW, который запрашивает переходные отношения, приведёт к тому, что действия по обеспечению внешнего ключа, вызванные одной командой SQL, будут разделены на несколько шагов, каждый со своими собственными переходными отношениями (или наборами отношений). В таких случаях любые присутствующие триггеры на уровне оператора будут срабатывать один раз за создание набора переходных отношений, гарантируя, что триггеры видят каждую затронутую строку в переходном отношении один и только один раз.

Триггеры на уровне оператора на представлении срабатывают только если действие над представлением обрабатывается построчным триггером INSTEAD OF. Если действие обрабатывается правилом INSTEAD, то любые операторы, порождённые правилом, выполняются вместо исходного оператора, называющего представление, так что триггеры, которые будут срабатывать, — это триггеры на таблицах, указанных в заменяющих операторах. Аналогично, если представление автоматически обновляемо, то действие обрабатывается автоматическим перезаписыванием оператора в действие над базовой таблицей представления, так что срабатывают триггеры на уровне оператора базовой таблицы.

Модификация секционированной таблицы или таблицы с дочерними таблицами наследования вызывает срабатывание триггеров на уровне оператора, прикреплённых к явно указанной таблице, но не триггеров на уровне оператора для её секций или дочерних таблиц. Напротив, построчные триггеры срабатывают на строках в затронутых секциях или дочерних таблицах, даже если они не указаны явно в запросе. Если триггер на уровне оператора был определён с переходными отношениями, указанными в предложении REFERENCING, то предыдущие и последующие образы строк видны из всех затронутых секций или дочерних таблиц. В случае дочерних таблиц наследования образы строк включают только столбцы, которые присутствуют в таблице, к которой прикреплён триггер.

В настоящее время построчные триггеры с переходными отношениями не могут быть определены на секциях или дочерних таблицах наследования. Также триггеры на секционированных таблицах не могут быть триггерами INSTEAD OF.

В настоящее время опция OR REPLACE не поддерживается для триггеров ограничений.

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

Существует несколько встроенных функций-триггеров, которые могут быть использованы для решения распространённых проблем без необходимости писать собственный код триггера; см. Раздел 2.6.29.

Примеры

Выполнять функцию check_account_update всякий раз, когда строка таблицы accounts собирается быть обновлена:

CREATE TRIGGER check_update
    BEFORE UPDATE ON accounts
    FOR EACH ROW
    EXECUTE FUNCTION check_account_update();

Изменить это определение триггера, чтобы функция выполнялась только если столбец balance указан в качестве цели в команде UPDATE:

CREATE OR REPLACE TRIGGER check_update
    BEFORE UPDATE OF balance ON accounts
    FOR EACH ROW
    EXECUTE FUNCTION check_account_update();

Эта форма выполняет функцию только если значение столбца balance фактически изменилось:

CREATE TRIGGER check_update
    BEFORE UPDATE ON accounts
    FOR EACH ROW
    WHEN (OLD.balance IS DISTINCT FROM NEW.balance)
    EXECUTE FUNCTION check_account_update();

Вызывать функцию для регистрации обновлений таблицы accounts, но только если что-то изменилось:

CREATE TRIGGER log_update
    AFTER UPDATE ON accounts
    FOR EACH ROW
    WHEN (OLD.* IS DISTINCT FROM NEW.*)
    EXECUTE FUNCTION log_account_update();

Выполнять функцию view_insert_row для каждой строки, чтобы вставлять строки в таблицы, лежащие в основе представления:

CREATE TRIGGER view_insert
    INSTEAD OF INSERT ON my_view
    FOR EACH ROW
    EXECUTE FUNCTION view_insert_row();

Выполнять функцию check_transfer_balances_to_zero для каждого оператора, чтобы подтвердить, что строки в таблице transfer компенсируются до нулевой суммы:

CREATE TRIGGER transfer_insert
    AFTER INSERT ON transfer
    REFERENCING NEW TABLE AS inserted
    FOR EACH STATEMENT
    EXECUTE FUNCTION check_transfer_balances_to_zero();

Выполнять функцию check_matching_pairs для каждой строки, чтобы подтвердить, что изменения вносятся в совпадающие пары одновременно (тем же оператором):

CREATE TRIGGER paired_items_update
    AFTER UPDATE ON paired_items
    REFERENCING NEW TABLE AS newtab OLD TABLE AS oldtab
    FOR EACH ROW
    EXECUTE FUNCTION check_matching_pairs();

Раздел 5.2.4 содержит полный пример функции-триггера, написанной на C.

Совместимость

Оператор CREATE TRIGGER в Digital Q.DataBase реализует подмножество стандарта SQL. В настоящее время отсутствуют следующие функциональные возможности:

  • Хотя имена переходных таблиц для триггеров AFTER указываются с помощью предложения REFERENCING стандартным способом, переменные строк, используемые в триггерах FOR EACH ROW, не могут быть указаны в предложении REFERENCING. Они доступны способом, который зависит от языка, на котором написана функция триггера, но фиксирован для любого конкретного языка. Некоторые языки эффективно ведут себя так, как если бы существовало предложение REFERENCING, содержащее OLD ROW AS OLD NEW ROW AS NEW.

  • Стандарт позволяет использовать переходные таблицы с триггерами UPDATE, специфичными для столбцов, но тогда набор строк, которые должны быть видны в переходных таблицах, зависит от списка столбцов триггера. Это в настоящее время не реализовано в Digital Q.DataBase.

  • Digital Q.DataBase позволяет выполнять только пользовательскую функцию в качестве действия триггера. Стандарт позволяет выполнять ряд других команд SQL, таких как CREATE TABLE, в качестве действия триггера. Это ограничение несложно обойти, создав пользовательскую функцию, которая выполняет нужные команды.

Стандарт SQL указывает, что несколько триггеров должны срабатывать в порядке их создания. В Digital Q.DataBase используется порядок по имени, который был признан более удобным.

Стандарт SQL указывает, что триггеры BEFORE DELETE на каскадных удалениях срабатывают после завершения каскадного удаления DELETE. В Digital Q.DataBase поведение таково, что BEFORE DELETE всегда срабатывает до действия удаления, даже каскадного. Это считается более последовательным. Также существует нестандартное поведение, если триггеры BEFORE изменяют строки или предотвращают обновления во время обновления, вызванного действием ссылочной целостности. Это может привести к нарушениям ограничений или хранимым данным, которые не соблюдают ссылочное ограничение.

Возможность указывать несколько действий для одного триггера с помощью OR является расширением Digital Q.DataBase по отношению к стандарту SQL.

Возможность срабатывания триггеров по команде TRUNCATE является расширением Digital Q.DataBase по отношению к стандарту SQL, как и возможность определять триггеры на уровне оператора на представлениях.

CREATE CONSTRAINT TRIGGER является расширением Digital Q.DataBase по отношению к стандарту SQL. Как и опция OR REPLACE.

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению