Проблема триггера INSTEAD OF INSERT - PullRequest
0 голосов
/ 29 апреля 2019

Я чувствую, что должен был

SET @InsertCount = COUNT (*) FROM INSERTED WHERE ISBN = @ISBN

, но это не позволило бы мне.Вместо этого я попытался использовать оператор SELECT, потому что видел, как кто-то другой использовал его в Интернете, но я не знаю, что еще делать.

IF OBJECT_ID ('BooksTrigger') IS NOT NULL
    DROP TRIGGER BooksTrigger
GO

-- create the trigger
CREATE TRIGGER BooksTrigger 
ON Books
INSTEAD OF INSERT
AS
    DECLARE @ISBN INT,
            @BookInDate DATE,
            @Memo VARCHAR(100),
            @Copies INT,
            @PreyQty INT,
            @InsertISBNCount INT,
            @CurrQty INT

    SET @InsertISBNCount = (SELECT COUNT(ISBN) FROM inserted WHERE ISBN = @ISBN)
    SET @PreyQty = (SELECT COUNT(ISBN) FROM Books WHERE ISBN = @ISBN)
    SET @CurrQty = (SELECT SUM(@InsertISBNCount + @PreyQty))
    SET @Copies = (SELECT CopiesNo FROM BookInfo WHERE ISBN = @ISBN)

    IF @Copies > @CurrQty
    BEGIN
        PRINT 'Inserting a copy of the book with ISBN ' + @ISBN

        INSERT INTO Books (ISBN, BookInDate, Memo)
        VALUES (@ISBN, @BookInDate, @Memo)
    END
    ELSE
        THROW 50027, 'Number of copies available for this book is less than the inserts for this book. Insert did not go through.', 1
GO

-- test
BEGIN TRY
    INSERT INTO Books 
    VALUES ('9780393248968', GETDATE(), 'test') --should print 'inserting'

    INSERT INTO Books 
    VALUES ('9780393248968', GETDATE(), 'test') --this one should throw an error as this would be the fifth book
END TRY
BEGIN CATCH
    PRINT ERROR_MESSAGE()
END CATCH

--see if the first one inserted
SELECT * FROM Books

Поэтому цель здесь - создать триггер INSTEAD OF для вставки данных.в таблице книг.Я хочу посмотреть, больше ли количество книг, вставленных в таблицу «Книги» для номера ISBN, чем число «Копии» в BookInfo для того же номера ISBN, сгенерировать ошибку, в противном случае вставить данные с сообщением печати «вставка…» или что-то в этом роде.

Мне сказали, что я должен увидеть подобное сообщение, когда я закончу:

Exprected Error Message

Но в настоящее время я получаю это:

Current Message

Вот код для создания двух таблиц (Книги И BookInfo)

--BookInfo Table
CREATE TABLE BookInfo
(
    ISBN BIGINT PRIMARY KEY CHECK (LEN([ISBN]) BETWEEN 10 AND 13),
    BookCategoryID INT,
    BookName VARCHAR(60),           
    BookAuthor VARCHAR(40),
    BookPublisher VARCHAR(40),
    BookPubDate DATE,
    BookPages INT CHECK (BookPages > 0),
    BookPrice INT CHECK (BookPrice > 0),
    CopiesNo INT DEFAULT 1 CHECK (CopiesNo > 0),
    Memo VARCHAR(100) NULL,
);

--Books Table
CREATE TABLE Books
(
    BookID INT PRIMARY KEY IDENTITY(1,1),
    ISBN BIGINT,
    BookInDate DATE,
    Memo VARCHAR(100) NULL, 
);
GO

ALTER TABLE Books
ADD FOREIGN KEY (ISBN) REFERENCES BookInfo(ISBN);
GO

INSERT INTO BookInfo (ISBN, BookCategoryID, BookName, BookAuthor,BookPublisher, BookPubDate, BookPages, BookPrice, CopiesNo, Memo)
VALUES (9780393248968, 1, 'Storm in a Teacup: The Physics of Everyday Life', 'Helen Czerski', 'W. W. Norton & Company', '01/10/2017', 288, 26.95, 4, 'On sale'),
       (9780062328502, 1, 'Dark Matter and the Dinosaurs: The Astounding', 'Lisa Randall', 'Ecco', '10/18/2016', 432, 17.99, 2, 'Not on Sale'),
       (9780262517263, 2, 'Grace Hopper and the Invention of the Information Age', 'Kurt Beyer', 'MIT Press', '02/01/2012', 404, 27.95, 2, 'On sale');

INSERT INTO Books (ISBN, BookInDate, Memo)
VALUES (9780393248968, '01/01/2018', 'this is a book'),
       (9780393248968, '01/01/2018', 'this is a book'),
       (9780393248968, '01/01/2018', 'this is a book'),
       (9780062328502, '01/02/2018', 'this is a book I think'),
       (9780062328502, '01/02/2018', 'this is a book I think'),
       (9780262517263, '01/03/2018', 'this is a book for sure'),
       (9780262517263, '01/03/2018', 'this is a book for sure');

1 Ответ

0 голосов
/ 29 апреля 2019

Я предполагаю, что вы пытаетесь предотвратить добавление большего количества записей Book, чем количество копий, настроенное в записи BookInfo для соответствующего ISBN.

Однако ваша логика проверяет только числоBook вставляется как часть этого оператора вставки (таблица inserted предназначена только для этой вставки).Поэтому, если разрешено только 4 копии книги, но вы вставляете их как 3 записи, а затем еще одна вставка из 3 записей (всего 6), ваш триггер позволит это.

Если вы следовали логике, чтобы решить эту проблемувам нужно сосчитать Book как в таблице Book, так и в таблице Inserted.

Однако вы можете решить проблему гораздо проще, используя триггер after,подсчет по таблице Book и откат в случае сбоя условия, например

create trigger BooksTrigger on Books
after Insert
as
begin
  -- if, for any BookInfo record, there exist more book records than CopiesNo, rollback
  if exists (select 1 from BookInfo BI where BI.CopiesNo < (select count(*) from Book B where B.ISBN = BI.ISBN)) begin
    ;THROW 50027, 'Number of copies available for this book is less than the inserts for this book. Insert did not go through.', 1
  end
end
...