sql - 添加约束以防止 SQL 更新触发器中的重复项

标签 sql triggers sql-update sql-insert

我们有一个用户表,每个用户都有一个唯一的电子邮件和用户名。我们尝试在我们的代码中执行此操作,但我们希望确保永远不会使用与电子邮件相同的用户名将用户插入(或更新)到数据库中。 我添加了一个 BEFORE INSERT 触发器来防止插入重复的用户。

CREATE TRIGGER [dbo].[BeforeUpdateUser]
   ON  [dbo].[Users]
   INSTEAD OF INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE @Email nvarchar(MAX)
    DECLARE @UserName nvarchar(MAX)
    DECLARE @UserId int
    DECLARE @DoInsert bit

    SET @DoInsert = 1

    SELECT @Email = Email, @UserName = UserName FROM INSERTED

    SELECT @UserId = UserId FROM Users WHERE Email = @Email

    IF (@UserId IS NOT NULL)
        BEGIN
            SET @DoInsert = 0
        END

    SELECT @UserId = UserId FROM Users WHERE UserName = @UserName

    IF (@UserId IS NOT NULL)
        BEGIN
            SET @DoInsert = 0
        END

    IF (@DoInsert = 1)
        BEGIN
            INSERT INTO Users
            SELECT 
                           FirstName, 
                           LastName, 
                           Email, 
                           Password, 
                           UserName, 
                           LanguageId,
                           Data, 
                           IsDeleted 
                       FROM INSERTED
        END
    ELSE
        BEGIN
            DECLARE @ErrorMessage nvarchar(MAX)
            SET @ErrorMessage = 
                         'The username and emailadress of a user must be unique!'
            RAISERROR 50001 @ErrorMessage
        END 
END

但是对于更新触发器,我不知道该怎么做。 我用谷歌找到了这个例子: http://www.devarticles.com/c/a/SQL-Server/Using-Triggers-In-MS-SQL-Server/2/ 但我不知道当您一次更新多个列时它是否适用。

编辑:

我试图在这些列上添加唯一约束,但它不起作用:

Msg 1919, Level 16, State 1, Line 1
Column 'Email' in table 'Users' is of a type 
that is invalid for use as a key column in an index.

最佳答案

您可以在表上添加一个唯一的约束,如果您尝试插入或更新并创建重复项,这将引发错误

ALTER TABLE [Users] ADD  CONSTRAINT [IX_UniqueUserEmail] UNIQUE NONCLUSTERED 
(
    [Email] ASC
)

ALTER TABLE [Users] ADD  CONSTRAINT [IX_UniqueUserName] UNIQUE NONCLUSTERED 
(
    [UserName] ASC
)

编辑:好的,我刚刚阅读了您对另一篇文章的评论,发现您正在使用 NVARCHAR(MAX) 作为数据类型。为什么您可能需要超过 4000 个字符的电子邮件地址或用户名?这就是你的问题所在。如果将其减少到 NVARCHAR(250) 左右,则可以使用唯一索引。

关于sql - 添加约束以防止 SQL 更新触发器中的重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/546101/

相关文章:

mysql - 根据另一个表中的值更新表

MySQL:如何将表A的数据复制到新的不存在的表B?

php - 从表单向数据库表插入多行

sql - 如何从闭包表中以 HTML 显示树结构

amazon-web-services - AWS : Trigger event if DynamoDB table row is not updated in the last 30 minutes

sql - T-SQL插入触发器在多个表上根据if条件插入、更新

mysql - 哪个更有效,DELETE 和 INSERT 或 INSERT 和 UPDATE

java - 使用 JOOQ 读取标记对象的推荐方法是什么?

git - Jenkins Git 构建触发器 : build every intermediate revision, 不只是 HEAD?

mysql - ZendDb - 用整数递增字段 - 添加 +1