SQL Server 2005 自动更新日期时间列 - LastUpdated
-
09-06-2019 - |
题
我定义了一个表(请参阅下面的代码片段)。如何添加约束或其他约束,以便在行更改时 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() 的默认值,然后使用触发器来处理任何更新。
只是像这样简单的事情:
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' 然后返回冲浪Myspace。然而,触发器并不关心姓氏已经是“Smith”,因此 LastUpdate 现在显示下午 2 点。
如果您只是在更新语句运行时盲目地更改 LastUpdate,那么它在技术上是正确的,因为确实发生了更新,但实际比较更改并采取相应行动可能更有意义。这样,同事的下午 2 点更新语句仍会运行,但 LastUpdate 仍会显示上午 8 点。
——凯文
我同意触发器的想法,尽管我会使用连接来插入而不是子查询。但是,我想指出,用户名对于主键来说是一个特别糟糕的选择。用户名经常更改,当更改时,您需要更改所有相关表。最好以用户 ID 作为键,然后在用户名上放置唯一索引。那么当用户名改变时,就不需要改变其他任何东西了。
为此,您必须使用触发器。
我的建议是创建一个存储过程,将 lastUpdate 默认为 getdate()。
过去我曾尝试避免使用触发器,因为在 SQL2005 之前定位和编辑它们是一件很痛苦的事情。特别是对于刚接触项目的开发人员。
还将其添加为列定义的默认值。