#sql-server #triggers
#sql-сервер #триггеры
Вопрос:
Предположим, у меня есть 3 таблицы
t1
Nid name
1 aaa
2 bbb
3 ccc
delT1
Nid name
t2
Sid Nid value
1 1 AAA
2 1 BAC
3 2 CSA
В таблице t1
Nid
находится первичный ключ, который является внешним ключом для t2
Теперь я хочу, чтобы при удалении значения из t1
оно автоматически удаляло все значения из t2
where t1.Nid=t2.Nid
, а значение deleted t1
вставлялось в delT1
Как я могу создать триггер для этого типа задачи?
Пожалуйста, помогите мне, поскольку я новичок в sql
Ответ №1:
Обычный триггер не сработал бы: внешний ключ выдал бы ошибку перед запуском кода.
Что вы можете сделать, так это установить КАСКАД для вашего внешнего ключа, чтобы удаление в T1 автоматически удаляло из T2.
Лично я бы использовал сохраненный процесс и транзакцию для удаления сначала из T2, затем из T1.
Комментарии:
1. хороший вызов, я не продумал, чего на самом деле пытался достичь плакат, и ограничение, выдающее ошибку
2. @lazyDBA: да, легко забывается. И, знаете, я не могу вспомнить, сработал бы триггер до / ВМЕСТО … 😉
Ответ №2:
Измените FK в T2 на ON DELETE CASCADE
:
ALTER TABLE T2 DROP CONSTRAINT FK_T1_Nid; <-- your constraint name here
ALTER TABLE T2 ADD CONSTRAINT FK_T1_Nid FOREIGN KEY (Nid)
REFERENCES T1 (Nid) ON DELETE CASCADE;
Затем создайте триггер на T1 для отправки информации в delT1:
CREATE TRIGGER TR_T1_D ON T1 FOR DELETE
AS
SET NOCOUNT ON;
INSERT delT1
SELECT Nid, Name
FROM Deleted;
Обратите внимание, что этот триггер предотвращает использование предложения OUTPUT при удалении для T1. БОЛ говорит:
Если предложение OUTPUT указано без указания ключевого слова INTO, для целевого объекта операции DML не может быть определен какой-либо активированный триггер для данного действия DML. Например, если предложение OUTPUT определено в инструкции UPDATE, в целевой таблице не может быть никаких включенных триггеров ОБНОВЛЕНИЯ.
Комментарии:
1. @gbn Да, потеря текста справа является проблемой, особенно на мобильных устройствах.
Ответ №3:
у @gbn есть предпочтительный путь. Поскольку вы запросили триггер, вы могли бы сделать это для сравнения:
CREATE TRIGGER t1_Delete ON t1
INSTEAD OF DELETE AS BEGIN SET NOCOUNT ON;
INSERT INTO delT1 (Nid, name)
SELECT Nid, name
FROM DELETED;
DELETE FROM t2
WHERE t2.Nid IN (SELECT Nid FROM DELETED);
DELETE FROM t1
WHERE t1.Nid IN (SELECT Nid FROM DELETED);
END;
Комментарии:
1. Вы забыли добавить
INSERT INTO delT1 ...
2. @Andriy M — Да, я уверен, что сделал — спасибо. Отредактировано, чтобы включить таблицу delT1.