Справка по триггеру SQL Server

#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.