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

#sql #sql-server-2019

#sql #sql-server-2019

Вопрос:

Мне было поручено создать образец библиотечной базы данных для школьного проекта. Пока что в основном все сделано, за исключением того, что мне нужно создать триггер, который срабатывает, когда библиотекарь пытается проверить книгу, которая еще не была возвращена предыдущим кредитором. Это код для вызываемой таблицы, LenderRecord который должен обусловливать вышеупомянутые вставки.

 CREATE TABLE LenderRecord
(
RecordID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
MediaID INT,
LenderID INT,
DateTaken DATE NOT NULL,
DateReturned DATE, --YYYY-MM-DD FORMAT!
Reservation NVARCHAR(20),
FineAmtDue MONEY DEFAULT '0',
FineAmtPaid MONEY DEFAULT '0'
);
  

Код для триггера: Пожалуйста, имейте в виду, что я новичок в SQL…

 CREATE TRIGGER trig_BookNotReturned  --This trigger fires when a mediaid is being inserted that has 
not bee returned by the previous lender.
ON LenderRecord
AFTER INSERT, UPDATE 
AS
BEGIN
    IF EXISTS( SELECT MediaID FROM inserted WHERE DateReturned = '1900-01-01' )
    BEGIN
        ROLLBACK TRANSACTION
        RAISERROR ('This book has not been returned yet', 16, 1)
    END
END
GO
  

Однако, когда я выполняю этот триггер и вставляю данные в таблицу, он фиксирует только вставки, у DateReturned которых нет ‘1900-01-01’.

Пожалуйста, кто-нибудь может подсказать мне лучший подход? Спасибо

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

1. можете ли вы привести пример вставляемой записи, которая, как вы ожидаете, сработает триггером, которого нет?

2. Не используйте фиктивные даты, такие как '1900-01-01' — оставьте значение NULL и проверьте по WHERE DateReturned IS NULL .

3. Я не думаю, что ваш триггер выполняет то, что вам нужно (если я не неправильно понимаю требования). Когда вы Select MediaId from inserted... , inserted таблица содержит только недавно добавленную / обновленную запись. Он не содержит всех LenderRecords для этого MediaID.

4. ВЫПОЛНИТЕ sp_LenderRecord_InsertUpdateDeleteSelect ’72’, ’26’, ‘2020-02-16’, «, «, «, «, ‘ Вставьте ‘ ВЫПОЛНИТЬ sp_LenderRecord_InsertUpdateDeleteSelect ’72’, ’29’, ‘2020-02-22’, «, «, «, «, ‘ Вставить’

Ответ №1:

Ваш запрос должен использовать INSERTED.MediaID , чтобы найти LenderRecord , где применяются оба условия:

 IF EXISTS( SELECT MediaID FROM LenderRecord WHERE MediaID = INSERTED.MediaID AND DateReturned = '1900-01-01' )
  

Однако это будет работать только на INSERT , поэтому ваш триггер должен срабатывать только на INSERT , а не на UPDATE .
Если вы включите свой триггер UPDATE , вы никогда не сможете установить DateReturned , потому что ваш триггер предотвратит это.

Также подумайте о том, чтобы оставить DateReturned значение NULL, пока у вас не будет действительной даты и фильтра для DateReturned IS NULL в вашем запросе.

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

1. Я получаю эту ошибку при попытке использования этого метода: Сообщение 4104, уровень 16, состояние 1, Процедура trig_BookNotReturned, строка 6 [Строка запуска пакета 1372] Вставлен многосоставный идентификатор «. Не удалось привязать MediaID».