我定义了一个表(请参阅下面的代码段)。如何添加约束或其他任何内容,以便在更改行时自动更新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
)
答案 0 :(得分:24)
我同意其他人 - 在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'(oops),LastUpdate默认为7am
上午8点 - “jsmith”通过电子邮件向IT人员说明他的名字不正确。您立即执行更新,因此姓氏现在是'Smith'并且(由于触发器)LastUpdate显示早上8点
2pm - 你的懒人同事终于厌倦了StumbleUpon并检查他的电子邮件。他看到了“jsmith”关于名称变更的早期信息。他运行: UPDATE配置文件SET LastName ='Smith'WHERE Username ='jsmith'然后去 回到MySpace冲浪。触发器并不关心姓氏是否已经是“史密斯”,所以LastUpdate现在显示为下午2点。
如果您只是在更新语句运行时盲目地更改LastUpdate,那么它在技术上是正确的,因为更新确实发生了,但实际比较更改并相应地采取行动可能更有意义。这样,同事下午2点更新声明仍会运行,但LastUpdate仍会显示早上8点。
- 凯文
答案 1 :(得分:4)
默认约束仅适用于插入;更新使用触发器。
答案 2 :(得分:3)
我同意触发器的想法,虽然我会使用连接插入而不是子查询。但是,我想指出用户名是主键的特别糟糕的选择。用户名经常更改,当他们这样做时,您需要更改所有相关表。将用户标识作为密钥然后在用户名上添加唯一索引要好得多。然后,当用户名更改时,您无需更改任何其他内容。
答案 3 :(得分:2)
你将不得不使用触发器。
答案 4 :(得分:-1)
我的建议是创建一个存储过程,将lastUpdate默认为getdate()。
我过去曾试图避免使用触发器,因为在SQL2005之前定位和编辑它们是一个痛苦的臀部。特别适合对您的项目不熟悉的开发人员。
同时将其添加为列定义的默认值。