对于我的学校项目,我需要为我的SQL Server数据库添加一个触发器。我决定在Users
表上使用“无双用户名”触发器是相关的。
问题是,每次执行INSERT
查询时都会触发此触发器。我无法弄清楚为什么每次都会发生这种情况。我甚至试过不同的方法来编写触发器。
我现在拥有的触发器:
CREATE TRIGGER [Trigger_NoDuplicates]
ON [dbo].[Users]
FOR INSERT
AS
BEGIN
SET NOCOUNT ON
IF(EXISTS(SELECT Username FROM Users
WHERE Username = (SELECT Username FROM inserted)))
BEGIN;
RAISERROR('This username already exists!',15, 0)
ROLLBACK
END
END
提前致谢!
答案 0 :(得分:2)
触发器每次都会触发,你的意思是“每次都会引发错误”吗?
您目前拥有以下(扩展为多行以使其更清晰)...
IF (
EXISTS (
SELECT Username
FROM users
WHERE Username = (SELECT Username FROM inserted)
)
)
这里的关键点是表inserted
的名称。过去式。它已经发生了。
inserted
表格中的任何内容已将 已 插入目标表格中。
那么,您需要检查的是用户名在目标表中 more 而不是一次。
但是 ,可以一次将多个记录插入到表中。这意味着Username = (SELECT Username FROM inserted)
会导致自己的错误。 (您无法将单个值与一组值进行比较,inserted
可以包含多个行=>多个用户名...)
这就是我接近你的触发器的方式......
IF EXISTS (
SELECT
users.Username
FROM
users
INNER JOIN
inserted
ON inserted.Username = users.Username
GROUP BY
users.Username
HAVING
COUNT(*) > 1
)
这将获取(已插入到)用户表,并使用inserted
表中的任何记录选取所有mach用户名的记录。
然后GROUP
按username
字段显示它们。
然后它将结果过滤到仅包含多于1条记录的组。
这些(用户名)组具有重复的条目,应该会导致触发器引发错误。
替代方案与您的方法更相似,但很多人不会认出来,所以我一般不会推荐它...
IF EXISTS (
SELECT
users.Username
FROM
users
WHERE
users.Username = ANY (SELECT username FROM inserted)
GROUP BY
users.Username
HAVING
COUNT(*) > 1
)
ANY
关键字很少使用,但听起来像是听起来像。它允许将单个值与一组值进行比较。
最后,如果您的表格中有IDENTITY
列,则可以通过明确声明您不想将某行与自身进行比较来避免GROUP BY
...
IF EXISTS (
SELECT
users.Username
FROM
users
INNER JOIN
inserted
ON inserted.Username = users.Username
AND inserted.id <> users.id
)