CREATE TRIGGER Prevent_Cast_Delete ON Cast
INSTEAD OF DELETE
AS
BEGIN
DELETE FROM Cast WHERE id IN (
--Identify only people who work in films with 0 or 1 cast members
SELECT d.id
FROM
--The list of people we try to delete (request from elsewhere)
Deleted d
LEFT OUTER JOIN
--This query counts the cast for every film
(SELECT CastFilmID, COUNT(*) as CastCount FROM Cast GROUP BY CastFilmId) c
ON
c.CastFilmID = d.CastFilmID
--This where clause reduces the list of actor IDs we try to delete, to actually
--just those actors who are in a film of 1 cast member
WHERE c.CountCast < 2 OR d.CastFilmID IS NULL
);
END;
Вы действительно забыли выполнить удаление внутри своего триггера, поэтому из вашей таблицы ничего не удалялось бы.
Я перевернул логику: для всех записей, которые вы пытаетесь удалить,
могут быть удалены только записи, относящиеся к актеру, который делит фильм с другим актером. * Для этого мы берем список людей, которые приложение (например) пыталось удалить, - deleted d
псевдотаблица, присоединяйтесь к немув сводку таблицы актеров и выбирайте только записи, в которых эта сумма насчитывает <2 актеров: </p>
Cast.ID, Cast.CastFilmID
KEANU, MATRIX
LAURE, MATRIX
HUGOW, MATRIX
JARAN, MOBYDI
JESUS, null
Предположим, я говорю delete from cast where id in ('KEANU','JARAN','JESUS')
- это пытается удалить людей из каждого фильма, который мы знаем.Он реализует псевдотаблица deleted
из:
Cast.ID, Cast.CastFilmID
KEANU, MATRIX
JARAN, MOBYDI
JESUS, null
. Слева на этот счет добавлено количество фильмов:
Cast.ID, Cast.CastFilmID, CastCount
KEANU, MATRIX, 3
JARAN, MOBYDI, 1
JESUS, null, null
Предложение WHERE удаляет KEANU из результатов, потому что он работает надфильм 3 актеров (включая его самого)
Следующие 2 записи запрошенных оригиналов 3 удалены (DELETE FROM cast WHERE ID IN (...this list...)
:
Cast.ID
JARAN
JESUS
Обратите внимание, что следующие предположения о вашей БД имеютбыло сделано:
- В таблице Cast есть столбец идентификаторов, уникальный для каждого актерского фильма
- CastFilmId - это идентификатор из таблицы фильмов, и он повторяется для всех, кто работает надтот же фильм
- Когда актер для фильма не снимается в этом фильме (возможно ли это?), я предположил, что его CastFilmID равен нулю. Если это никогда не будет равно нулю, можно было бы внести некоторые упрощения в запрос, но в этой форме я предполагал, что записи, в которых актер не назначен для фильма, все еще могут быть удалены
Здесь важно понять, что кто-то, выполняющий запрос на удаление, будетдать вам X количество строк в вашем триггере;это те строки, которые человек пытается удалить, но вам нужно дополнительные знания извне этого набора данных (например, «сколько других людей работают над теми же фильмами, что и каждый из этих людей»), прежде чем вы сможетерешить, удалять их или нет.Вот почему мы подсчитываем количество людей в этом фильме, присоединяем его к данным удаляемого человека и ТОГДА решаем, следует ли удалить этого человека
Действительно, этот вид магии должен быть сделан впередний конец.Все становится очень запутанным, когда вы говорите БД удалить что-то, а это не так.Точно так же вам следует помнить, что запросы DELETE могут удалять сотни строк за раз, поэтому вы не можете использовать упрощенный подход «удаление будет когда-либо пытаться удалить только одну строку преобразования» - вы должны работать над этими вещами, какнаборы данных, объедините их с другими наборами данных и получите набор данных, который необходимо удалить