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