SQL Server触发器 - 修改id列

时间:2014-04-29 06:40:11

标签: sql-server triggers sql-server-2012

经过数小时的谷歌搜索和搜索,我可以创建此触发器;此触发器运行良好,并使两个表在两个不同的表中保持同步。 (我不担心批量操作,这不会发生)。唯一的问题是如果USER_ID被修改(即主键),它不会在第二个表中更新);我无法获得'更新'部分。我做错了什么?

ALTER TRIGGER [u].[SyncUsers] 
   ON  [u].[USERS] 
   AFTER INSERT,DELETE,UPDATE
AS 

BEGIN

    IF (@@rowcount = 0) RETURN;
    SET NOCOUNT ON;

    -- deleted data
    IF NOT EXISTS (SELECT * FROM inserted) 
        BEGIN
            DELETE FROM ERP_DB.u.USERS WHERE USER_ID = 
            (SELECT USER_ID FROM deleted);
            RETURN;
        END
    ELSE 
        BEGIN

            -- inserted data
            IF NOT EXISTS (SELECT * FROM deleted)
                BEGIN           
                    INSERT INTO ERP_DB.u.USERS(USER_ID, USER_NAME , DISPLAY_NAME , EMP_ID , DEPARTMENT_ID)  SELECT USER_ID, USER_NAME , DISPLAY_NAME , EMP_ID , DEPARTMENT_ID FROM inserted;
                    RETURN;
                END

            -- updated data
            ELSE
                BEGIN
                    UPDATE UU
                        SET UU.USER_ID = i.USER_ID,
                            UU.USER_NAME = i.USER_NAME ,
                            UU.DISPLAY_NAME = i.DISPLAY_NAME ,
                            UU.DEPARTMENT_ID = i.DEPARTMENT_ID ,
                            UU.EMP_ID = i.EMP_ID 

                            FROM ERP_DB.u.USERS AS UU
                INNER JOIN Inserted AS i ON UU.USER_ID = i.USER_ID

            RETURN;
        END 
    END -- updated data
    END
END

2 个答案:

答案 0 :(得分:1)

您永远不应该修改主键。

如果某些内容可以修改,则不能成为主键

主键通常应为Auto Generated,且必须只读

因此,您所假设的可能是错误的,或者您的数据库设计是错误的。

如果主键为editable,则无法确保uniqueness 违反主键质量

希望这会有所帮助..

答案 1 :(得分:1)

当然它没有,因为桌子的PK被改变了。 user_id伪表中的inserted列的值与UU表中的值不同。您需要已删除表格中的值与user_id列以及inserted中的所有其他内容匹配。但问题是,当PK被更改时,无法再匹配inserteddeleted表。一团糟。

如果它始终是单行更新,您可以使用UU和inserted之间的交叉连接以及`WHERE UU.user_id =(SELECT user_id from deleted)& #39;在更新声明中。

Mutch更好 - 完全禁止PK更新。毕竟,如果PK改变了,它就不再是同一行了。