如何防止触发器触发,以便不将重复数据输入 table
How to prevent a trigger from firing so that duplicate data is not entered into a table
假设我有 3 个这样的 table:
authorGenres (authorGenreId, authorId, isPublished)
bookLibrarys (bookLibraryId, authorGenreId, bookId)
bookList (bookId, authorId)
我创建了一个触发器,当在 authorGenres
中更新行并且 isPublished
列设置为 1
.
时触发
发生这种情况时,触发器将一行插入 bookLibrarys
table,其中 authorGenreId
列设置为在 authorGenres
[= 中更新的行25=]
这是我的工作触发器:
ALTER TRIGGER [dbo].[setCorrectGenreAfterUpdate]
ON [dbo].[authorGenres]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @bookID AS NVARCHAR(50);
DECLARE @bookLibraryId AS UNIQUEIDENTIFIER;
DECLARE @author IDUNIQUEIDENTIFIER;
SELECT @authorID = Inserted.authorID FROM inserted;
SET @bookLibraryId = NEWID();
SET @bookID = ( SELECT bookId
FROM booklist nl
WHERE nl.authorID = @authorID)
INSERT INTO booklibrarys(bookLibraryID, parentBookID, genreID)
SELECT @bookLibraryId, @bookID, genreID FROM Inserted
END
当我像这样 UPDATE dbo.authorGenres SET isPublished = 1 WHERE genreID = 'C325061D-4274-487B-93F9-03BEB8B7D4D5'
进行测试 UPDATE 时,它会工作并将新行插入 bookLibrarys
。
问题是,如果我再次执行该更新,我会在 bookLibrarys
中得到另一个新行,它具有相同的 authorGenreId 和 bookId,但是一个新的 bookLibraryId,因为它是在触发器中生成的。
如果 bookLibrarys
中不存在具有该 bookId 和 authorGenreId 的行,是否有办法仅 运行 触发?
谢谢!
尝试使用 LEFT JOIN 来检查相同的记录是否已经存在,并确保按照@Lamu 在评论中向您建议的那样具有适用于多行的代码。
像这样:
ALTER TRIGGER [dbo].[setCorrectGenreAfterUpdate]
ON [dbo].[authorGenres]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO booklibrarys(bookLibraryID, parentBookID, genreID)
SELECT NEWID(), bl.bookId, ins.genreID FROM Inserted ins
INNER JOIN booklist bl ON bl.authorID = ins.authorID -- this is to get bookId for each row, not for one like in variable
LEFT JOIN booklibrarys blib ON blib.genreID = ins.genreID AND bl.bookId =
blib.parentBookID
WHERE blib.bookLibraryID is NULL
END
假设我有 3 个这样的 table:
authorGenres (authorGenreId, authorId, isPublished)
bookLibrarys (bookLibraryId, authorGenreId, bookId)
bookList (bookId, authorId)
我创建了一个触发器,当在 authorGenres
中更新行并且 isPublished
列设置为 1
.
发生这种情况时,触发器将一行插入 bookLibrarys
table,其中 authorGenreId
列设置为在 authorGenres
[= 中更新的行25=]
这是我的工作触发器:
ALTER TRIGGER [dbo].[setCorrectGenreAfterUpdate]
ON [dbo].[authorGenres]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @bookID AS NVARCHAR(50);
DECLARE @bookLibraryId AS UNIQUEIDENTIFIER;
DECLARE @author IDUNIQUEIDENTIFIER;
SELECT @authorID = Inserted.authorID FROM inserted;
SET @bookLibraryId = NEWID();
SET @bookID = ( SELECT bookId
FROM booklist nl
WHERE nl.authorID = @authorID)
INSERT INTO booklibrarys(bookLibraryID, parentBookID, genreID)
SELECT @bookLibraryId, @bookID, genreID FROM Inserted
END
当我像这样 UPDATE dbo.authorGenres SET isPublished = 1 WHERE genreID = 'C325061D-4274-487B-93F9-03BEB8B7D4D5'
进行测试 UPDATE 时,它会工作并将新行插入 bookLibrarys
。
问题是,如果我再次执行该更新,我会在 bookLibrarys
中得到另一个新行,它具有相同的 authorGenreId 和 bookId,但是一个新的 bookLibraryId,因为它是在触发器中生成的。
如果 bookLibrarys
中不存在具有该 bookId 和 authorGenreId 的行,是否有办法仅 运行 触发?
谢谢!
尝试使用 LEFT JOIN 来检查相同的记录是否已经存在,并确保按照@Lamu 在评论中向您建议的那样具有适用于多行的代码。
像这样:
ALTER TRIGGER [dbo].[setCorrectGenreAfterUpdate]
ON [dbo].[authorGenres]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO booklibrarys(bookLibraryID, parentBookID, genreID)
SELECT NEWID(), bl.bookId, ins.genreID FROM Inserted ins
INNER JOIN booklist bl ON bl.authorID = ins.authorID -- this is to get bookId for each row, not for one like in variable
LEFT JOIN booklibrarys blib ON blib.genreID = ins.genreID AND bl.bookId =
blib.parentBookID
WHERE blib.bookLibraryID is NULL
END