SQL после обновления вызывает путаницу

#sql #sql-server #triggers

#sql #sql-сервер #триггеры

Вопрос:

Я надеюсь, что кто-нибудь сможет мне помочь. Это мой первый пост в истории, поэтому я надеюсь, что хорошо его объяснил.

Я использую Microsoft SQL Management Studio.

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

Итак, я создаю триггер для таблицы Person, где у меня есть первичный ключ ID_Person, имя, фамилия и Personal_numb. Кроме того, я создал таблицу под названием Аренда, в которой у меня есть столбцы: первичный ключ ID_Renting, внешний ключ ID_Person, внешний ключ ID_Computer и столбцы Date_Rented и Date_Returned.. Вот как выглядит мой код:

 create trigger NO
On Person
after update
as
 begin
 if update(Personal_numb)
 
 (select ID_Person from Renting
 where Renting.Date_Returned is null)
 begin
 Raiserror('Person needs to return the computer before you try to change their personal number!', 16,1)
 end
 end
 

Однако я знаю, что мне чего-то не хватает между if update (Personal_numb) и select, но что это?

Комментарии:

1. вам необходимо использовать inserted для получения ID_Person , а затем JOIN для Renting и проверки Date_Returned

2. Хорошо, я попытался использовать inserted и deleted, но я не знаю, как их подключить, чтобы это имело смысл в триггере обновления. Можете ли вы дать мне подсказку о том, как сделать так, чтобы триггер обновления выглядел нормально в любом другом примере, где я делаю это для одной таблицы и проверяю условие для другой?

3. Давайте сделаем шаг назад. Почему у вас есть это ограничение? Используете ли вы этот столбец в других таблицах (например, dbo.Renting)? Возможно, вам просто не следует разрешать изменять этот столбец вообще?

4. Это часть задания, которое я должен был выполнить, и все остальное я сделал правильно, кроме этой части. Я знаю, что могу установить ограничение, чтобы не разрешить изменять все это. Все это было просто для практики, не более того.

Ответ №1:

Вы могли бы попробовать что-то вроде этого

 drop trigger if exists trg_Person_upd;
go
create trigger trg_Person_upd on Person
after update
as
set nocount on;

if exists(select * from inserted);
    begin
         if exists (select * 
                    from Renting r
                         join inserted i on r.ID_Person=i.ID_Person
                         join deleted d on r.ID_Person=d.ID_Person
                    where i.Personal_numb<>d.Personal_numb
                          and r.Date_Returned is null))
        throw 50000, 'Person needs to return the computer before you try to change their personal number!', 1;
     end
 

Ответ №2:

Что-то вроде этого.

Вы используете inserted для присоединения к renting и проверки Date_Rreturned использования EXISTS()

Примечание: я изменил имя триггера. Название его NO довольно необычное

 create trigger TR_Person
On Person
after update
as
begin
    if  update(Personal_numb)
    and exists
        (
            select  *
            from    inserted i  
                    inner join Renting r    on  i.ID    = r.ID_Person
            where   r.Date_Returned     is null
        )
    begin
        Raiserror('Person needs to return the computer before you try to change their personal number!', 16,1)
    end
 end
 go
 

Комментарии:

1. Хорошо, теперь я понял. Мне просто не хватало части «и существует». Большое вам спасибо!

2. А также inserted то , что . Вам нужно использовать inserted для определения строк, на которые влияет update оператор. Пожалуйста, примите ответ, который решит вашу проблему

3. Хорошо, да. Когда я использовал триггеры удаления и вставки, я использовал inserted и deleted, но до сих пор я никогда не использовал update trigger, поэтому я не знал, где реализовать вставленную таблицу, но теперь у меня все хорошо. Спасибо!