Триггеры в БД, выполняемые после «набора» операторов вставки - PullRequest
7 голосов
/ 07 декабря 2011

У меня есть таблица, в которой хранятся события.

Однако при проектировании системы события обычно записываются партиями.Под этим я подразумеваю, что набор событий (около 10) обычно записывается вместе, а не просто как отдельные события.

Мы можем предположить, что: в таблице событий есть столбец с именем «batch_no»Таким образом, мы знаем, какие события принадлежат к какому номеру пакета.

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

Решения, о которых я думал, включают в себя что-то вроде: (а) определения триггера для каждой строки;(б) при условии, что рассчитывается количество (выберите * из событий, где NEW.batchNO = events.batchNO);задержка на некоторое время;снова вычислите то же количество, и если они равны, мы знаем, что пакет завершил загрузку, и вызываем триггер.

Хотя, очевидно, решение, представленное выше, звучит сложно?Есть ли более лучшее или простое решение?(Или, если нет, какая-нибудь помощь в том, как я мог реализовать то, что я описал?)

1 Ответ

6 голосов
/ 07 декабря 2011

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

Вам нужен триггер, чтобы сработать в состоянии, которое не известно во время создания триггера. Я вижу в основном три возможности:

1) Триггер уровня оператора

Использование предложения FOR EACH STATEMENT. Я цитирую руководство здесь :

триггер, помеченный ДЛЯ КАЖДОГО ЗАЯВЛЕНИЯ, выполняется только один раз для любого данная операция, независимо от того, сколько строк она изменяет (в В частности, операция, которая изменяет ноль строк, все равно приведет к выполнение любых применимых триггеров FOR EACH STATEMENT).

Применяется только в том случае, если вы вставляете все свои партии одной командой INSERT (несколько строк), но не более одного пакета за раз.

2) Условие WHEN для триггера уровня строки.

Использование предложения FOR EACH STATEMENT плюс условие WHEN. Для этого вам нужна версия 9.0+.
Если вы можете узнать из единственной вставленной строки , которая является последней в пакете, тогда ваше определение триггера может выглядеть следующим образом:

CREATE TRIGGER insert_after_batch
AFTER INSERT ON tbl
FOR EACH ROW
WHEN (NEW.batch_last)
EXECUTE PROCEDURE trg_tbl_insert_after_batch();

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

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

3) Условный код внутри вашего триггера

Это в основном запасной вариант для версий до 9.0, где у вас еще нет условия WHEN. Сделайте ту же проверку внутри триггера перед выполнением полезной нагрузки. Дороже, чем при условии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...