Мне нужно написать триггер вставки и обновления для таблицы A, который удалит все строки из таблицы B, один столбец (скажем, Desc) имеет значения, подобные значению, вставленному / обновленному в столбце таблицы A (скажем, Col1). Как бы мне написать его так, чтобы я мог обрабатывать как обновления, так и вставки. Как бы я определить, если триггер выполняется для обновления или вставки.
источник
источник
Многие из этих предложений не учитываются, если вы запускаете оператор удаления, который ничего не удаляет.
Допустим, вы пытаетесь удалить, если идентификатор равен некоторому значению, которого нет в таблице.
Ваш триггер все еще вызывается, но в удаленных или вставленных таблицах ничего нет.
Используйте это, чтобы быть в безопасности:
Отдельное спасибо @KenDog и @Net_Prog за их ответы.
Я построил это из своих сценариев.
источник
Я использую следующее, он также правильно определяет операторы удаления, которые ничего не удаляют:
источник
После долгих поисков я не смог найти точный пример одного триггера SQL Server, который обрабатывает все (3) три условия действий триггера INSERT, UPDATE и DELETE. Наконец, я нашел строку текста, в которой говорилось о том, что при возникновении DELETE или UPDATE общая таблица DELETED будет содержать запись для этих двух действий. На основании этой информации я создал небольшую подпрограмму Action, которая определяет, почему триггер был активирован. Этот тип интерфейса иногда необходим, когда для триггера INSERT vs. UPDATE необходимо выполнить как общую конфигурацию, так и специальное действие. В этих случаях создание отдельного триггера для ОБНОВЛЕНИЯ и ВСТАВКИ стало бы проблемой обслуживания. (то есть были ли оба триггера обновлены правильно для необходимого исправления общего алгоритма данных?)
С этой целью я хотел бы дать следующий фрагмент кода события нескольких триггеров для обработки INSERT, UPDATE, DELETE в одном триггере для Microsoft SQL Server.
источник
Я считаю, что вложенные, если немного сбивают с толку и:
;)
источник
источник
Попробуй это..
источник
хотя мне также нравится ответ, опубликованный @Alex, я предлагаю этот вариант решения @ Грэма выше
он использует исключительно существование записей в таблицах INSERTED и UPDATED, в отличие от использования COLUMNS_UPDATED для первого теста. Это также предоставляет параноику программисту облегчение, зная, что окончательный случай был рассмотрен ...
вы получите NOOP с заявлением, подобным следующему:
источник
END
отступ с ошибкой! (вызывает вопрос, где первоеBEGIN
закрыто)Это может быть более быстрый способ:
источник
Потенциальная проблема с двумя предлагаемыми решениями заключается в том, что в зависимости от того, как они написаны, запрос на обновление может обновить ноль записей, а запрос на вставку может вставить ноль записей. В этих случаях наборы вставленных и удаленных записей будут пустыми. Во многих случаях, если оба набора записей Inserted и Deleted пусты, вы можете просто выйти из триггера, ничего не делая.
источник
Я нашел небольшую ошибку в Grahams, иначе классное решение:
Это должно быть IF COLUMNS_UPDATED () < > 0 - вставить или обновить
вместо> 0, вероятно, потому что старший бит интерпретируется как целочисленный бит знака SIGNED ... (?). Итак, всего:
источник
Это делает трюк для меня:
Поскольку не все столбцы могут быть обновлены одновременно, вы можете проверить, обновляется ли определенный столбец чем-то вроде этого:
источник
источник
Мне нравятся решения, которые "элегантны в компьютерных науках". Мое решение здесь обращается к псевдотаблям [вставлено] и [удалено] один раз, чтобы получить их статусы, и помещает результат в битовую переменную. Тогда каждая возможная комбинация INSERT, UPDATE и DELETE может быть легко протестирована в течение всего триггера с эффективными двоичными оценками (за исключением маловероятной комбинации INSERT или DELETE).
Предполагается, что не имеет значения, каким был оператор DML, если строки не были изменены (что должно удовлетворять подавляющему большинству случаев). Так что, хотя оно не так полно, как решение Романа Пекара, оно более эффективно.
При таком подходе у нас есть возможность одного триггера «FOR INSERT, UPDATE, DELETE» на таблицу, что дает нам A) полный контроль над порядком действий и b) одну реализацию кода на действие, применимое к нескольким действиям. (Очевидно, что каждая модель реализации имеет свои плюсы и минусы; вам нужно будет оценивать свои системы индивидуально на предмет того, что действительно работает лучше всего.)
Обратите внимание, что операторы «существует (выберите * из« вставлено / удалено »)» очень эффективны, поскольку нет доступа к диску ( https://social.msdn.microsoft.com/Forums/en-US/01744422-23fe-42f6 -9ab0-a255cdf2904a ).
источник
Быстрое решение MySQL
Кстати: я использую MySQL PDO.
(1) В таблице автоинкремента просто получите самое высокое значение (имя моего столбца = id) из увеличенного столбца, как только каждый сценарий будет запущен первым:
(2) Запустите запрос MySQL, как обычно, и приведите результат к целому числу, например:
(3) После запроса «INSERT INTO ... ON DUPLICATE KEY UPDATE» получите последний вставленный идентификатор вашего предпочтительного способа, например:
(4) Сравните и отреагируйте: если lastInsertId выше самого высокого в таблице, это, вероятно, INSERT, верно? И наоборот.
Я знаю, что это быстро и, возможно, грязно. И это старый пост. Но, эй, я долго искал решение, и, возможно, кто-то найдет мой путь в любом случае полезным. Всего наилучшего!
источник
простой способ
источник
В первом сценарии я предположил, что в вашей таблице есть столбец IDENTITY
Во втором сценарии не нужно использовать столбец IDENTITTY
источник
Если его обновление
если его вставка
источник
Я использовал эти
exists (select * from inserted/deleted)
запросы в течение длительного времени, но этого все еще недостаточно для пустых операций CRUD (когда в таблицахinserted
и записях нет записейdeleted
). Поэтому, немного изучив эту тему, я нашел более точное решение:Также можно использовать,
columns_updated() & power(2, column_id - 1) > 0
чтобы увидеть, обновлен ли столбец, но это небезопасно для таблиц с большим количеством столбцов. Я использовал немного сложный способ расчета (см. Полезную статью ниже).Кроме того, этот подход по-прежнему некорректно классифицирует некоторые обновления как вставки (если обновление затрагивает каждый столбец таблицы), и, вероятно, он будет классифицировать вставки, где вставляются только значения по умолчанию, как удаления, но они являются королем редких операций (при сдавай в мою систему они есть). Кроме того, я не знаю, как улучшить это решение в настоящее время.
источник
источник
я сделаю это:
1 -> вставить
2 -> удалить
3 -> обновить
источник
источник