SQL Server 2005自动更新的DateTime列-LastUpdated

时间:2020-03-05 18:45:27  来源:igfitidea点击:

我定义了一个表(请参见下面的代码片段)。如何添加约束或者任何约束,以便在更改行时自动更新LastUpdate列?

CREATE TABLE dbo.Profiles
(
        UserName                                varchar(100)            NOT NULL,
        LastUpdate                              datetime                NOT NULL  CONSTRAINT DF_Profiles_LastUpdate DEFAULT (getdate()),
        FullName                                varchar(50)             NOT NULL,
        Birthdate                               smalldatetime           NULL,
        PageSize                                int                     NOT NULL CONSTRAINT DF_Profiles_PageSize DEFAULT ((10)),
        CONSTRAINT PK_Profiles PRIMARY KEY CLUSTERED (UserName ASC),
        CONSTRAINT FK_Profils_Users FOREIGN KEY (UserName) REFERENCES dbo.Users (UserName) ON UPDATE CASCADE ON DELETE CASCADE  
)

解决方案

回答

我们将必须为此使用触发器。

回答

默认约束仅适用于插入;要进行更新,请使用触发器。

回答

我的建议是创建一个存储过程,将lastUpdate默认为getdate()。

在过去,我曾尝试避免使用触发器,因为SQL2005之前的版本很难找到并编辑触发器。特别是对于项目不熟悉的开发人员。

还要将其添加为列定义的默认值。

回答

我同意其他意见-在LastUpdate列上设置GetDate()的默认值,然后使用触发器来处理所有更新。

就像这样简单:

CREATE TRIGGER KeepUpdated on Profiles
FOR UPDATE, INSERT AS 
UPDATE dbo.Profiles 
SET LastUpdate = GetDate()
WHERE Username IN (SELECT Username FROM inserted)

如果我们真的想花哨的话,让它评估正在更改的内容与数据库中的内容,并且仅在存在差异时才修改LastUpdate。

考虑一下...

  • 上午7点-创建的用户" jsmith"的姓氏为" Smithe"(哎呀),LastUpdate默认为上午7点
  • 上午8点-" jsmith"通过电子邮件向IT部门说他的名字不正确。我们立即执行更新,因此姓氏现在为" Smith",并且(由于触发器而已)LastUpdate显示上午8点。
  • 下午2点-懒惰的同事终于对StumbleUpon感到无聊,并检查了他的电子邮件。他看到了来自" jsmith"的较早消息,内容涉及更名。他运行:更新配置文件SET LastName ='Smith'WHERE Username ='jsmith',然后返回网上冲浪。触发器并不关心姓氏已经是" Smith",但是,LastUpdate现在显示2pm。

如果我们只要在运行更新语句时就盲目更改LastUpdate,则从技术上讲是正确的,因为确实发生了更新,但是实际比较更改并采取相应措施可能更有意义。这样,该同事的2pm Update语句仍将运行,但LastUpdate仍将显示上午8点。

-凯文

回答

我同意触发器的想法,尽管我将使用联接来插入而不是子查询。但是,我想指出的是,用户名对于主键来说是一个特别糟糕的选择。用户名经常更改,并且我们需要更改所有相关表。最好以用户ID为键,然后在用户名上添加唯一索引。然后,当用户名更改时,我们无需更改其他任何内容。