Триггеры sql

Привет, IT-сообщество. Помогите разобраться с правильным созданием триггеров в этих двух задачах:

  1. Триггер не позволяющий удалять диски группы The Beatles

Я попытался написать, но оно не работает вообще. Ничего не удаляется, если диск не попадает в условия. Перепробовал почти все, но никак. Может это как то связано с внешним ключом?

create trigger tg_beatles_delete_taboo on Discs
instead of delete
as
begin
declare @id int
select @id=SingerId from inserted
if exists(select SingerId from Discs d 
   join Singers s on s.Id=d.SingerId
   where SingerId=@id and s.Name=N'The Beatles')
   begin
     print ('Sorry, you can not delete discs of this group')
     rollback transaction
   end
else
   begin
   delete from Discs
   where exists (select SingerId from Discs d 
   join Singers s on s.Id=d.SingerId
   where SingerId=@id)
   end
end

И вторая задача для другой бд

  1. При удалении информации о покупателе триггер переносит
    его историю покупок в таблицу «История покупок»

Тут вылетает ошибка, связанная со ссылочным ограничением

create trigger tg_purchase_history on Clients
instead of delete
as
begin
insert into PurchaseHistory(EmpId,ClientId,Product,Price,SDate)
select EmpId,ClientId,Product,Price,SDate
from SaleOfGoods sg join deleted d
on d.Id=sg.ClientId
delete from Clients
where Id in (select Id from deleted)
end

Вот базы данных Sales_db.txt (2.4 КБ) Music_Collection_db.txt (3.9 КБ)

Так тут exists не нужен, он же был в if, просто where с id диска.

1 лайк

Блин, точно. Спасибо) Осталось понять, что во втором не так
Вот такая ошибка выскакивает:

Msg 547, Level 16, State 0, Procedure tg_purchase_history, Line 11 [Batch Start Line 68]
The DELETE statement conflicted with the REFERENCE constraint “FK__PurchaseH__Clien__47DBAE45”. The conflict occurred in database “Sales_db”, table “dbo.PurchaseHistory”, column ‘ClientId’

Может это как-то связано с тем, что у меня установлен ON DELETE CASCADE. I have no idea!

Так а как таблица PurchaseHistory создается?
Тут ее нет

Я ее создал при создании триггера, то есть перед созданием

create table PurchaseHistory
([Id] int not null identity(1, 1) primary key,
[EmpId] int not null foreign key references [Employees]([Id]),
[ClientId] int not null foreign key references [Clients]([Id]),
[Product] nvarchar(max) not null check ([Product] <> N''),
[Price] money not null check ([Price] >= 0.0) default 0.0,
[SDate] date not null check (SDate <= getdate()) default getdate())
go

Так покупателя в этой таблице видимо не должно быть, иначе как удалять?

А как тогда сохранить историю?

Зависит от задачи :man_shrugging:

Может предполагалось, что это история без покупателя, только что/когда/за сколько продано.

Я уже и сам не знаю. Как сделать так, чтобы нормально записывались данные в историю с одной таблицы при удалении из другой. Ну уберу я клиента из истории, разве это поможет?

Так он же удаляется, значит и ссылки на него не может быть.

Текст ошибки не особо понятный, но видимо он про то, что ClientId в этой таблице связан с элементом в таблице Clients, поэтому его нельзя удалить.

Сделал таким образом: добавил в таблицу клиентов еще один столбец “Примечания” и вместо удаления добавляю туда запись, что “Его песенка спета”. Ничего умнее придумать не смог. А так все работает.