关于 DateCreated 和 DateModified 列的问题 - SQL Server
Posted
技术标签:
【中文标题】关于 DateCreated 和 DateModified 列的问题 - SQL Server【英文标题】:Question About DateCreated and DateModified Columns - SQL Server 【发布时间】:2010-04-09 19:39:44 【问题描述】:CREATE TABLE Customer
(
customerID int identity (500,20) CONSTRAINT
.
.
dateCreated datetime DEFAULT GetDate() NOT NULL,
dateModified datetime DEFAULT GetDate() NOT NULL
);
当我插入一条记录时,dateCreated 和 dateModified 被设置为默认日期/时间。当我更新/修改记录时,dateModified 和 dateCreated 保持原样?我该怎么办?
显然,我需要 dateCreated 值保持第一次插入时的状态,并且当记录字段中发生更改/修改时,dateModified 会不断变化。
换句话说,你能写一个示例快速触发器吗?我还不太了解...
【问题讨论】:
在您的更新查询中,为什么不直接重置 dateModified = GetDate()? 我想让它自动... 【参考方案1】:您可能希望创建一个更新触发器来为您更新此值
看看类似的东西
CREATE TABLE Vals(
ID INT,
Val VARCHAR(10),
DateCreated DATETIME DEFAULT GetDate(),
DateUpdated DATETIME DEFAULT GetDate()
)
GO
CREATE TRIGGER Upd ON Vals
AFTER UPDATE
AS
UPDATE Vals
SET DateUpdated = GetDate()
FROM Vals INNER JOIN
inserted ON Vals.ID = inserted.ID
Go
INSERT INTO Vals (ID, Val) SELECT 1, 'A'
SELECT *
FROM Vals
GO
UPDATE Vals SET Val = 'B'
SELECT *
FROM Vals
GO
DROP TABLE Vals
GO
【讨论】:
使用 INSERTED 而不是 DELETED 不是更好吗,如果您的更新更改了 PK(这真的很糟糕),这将不起作用,还是我遗漏了什么?【参考方案2】:UPDATE
Customer
SET
... = NewValue,
dateModified = DEFAULT
WHERE
...
我会使用这个而不是dateModified = GETDATE()
,所以 GETDATE() 只使用一次(假设你想在将来更改为 GETUTCDATE())
如果您有多个更新路径,则为触发器...?
【讨论】:
如果你真的需要,搜索和替换在GETDATE
这样的东西上会很好用【参考方案3】:
当我插入一条记录时,dateCreated 并且 dateModified 被设置为默认值 约会时间。当我更新/修改 记录、日期修改和日期创建 保持原样?我该怎么办?
仅当INSERT
ing 时使用列默认值,而不是UPDATE
。如果您不提供列或在 INSERT 中发出 DEFAULT
关键字,则 INSERT 命令将使用默认值。
INSERT INTO Customer (col1, col2)
VALUES (..,..) ---get default for dateCreated & dateModified
INSERT INTO Customer (col1, col2,dateCreated)
VALUES (..,..,DEFAULT) ---get default for dateCreated & dateModified
INSERT INTO Customer (col1, col2,dateCreated,dateModified)
VALUES (..,..,DEFAULT,DEFAULT) ---get default for dateCreated & dateModified
INSERT INTO Customer (col1, col2,dateCreated,dateModified)
VALUES (..,..,'1/1/2010',DEFAULT) ---only get default for dateModified
INSERT INTO Customer (col1, col2,dateCreated,)
VALUES (..,..,'1/1/2010') ---only get default for dateModified
INSERT INTO Customer (col1, col2,dateCreated,dateModified)
VALUES (..,..,'1/1/2010','1/2/2010') ---no defaults for dateCreated & dateModifie
我喜欢用一个局部变量来设置那个程序的顶部:
DECLARE @RunDate datetime
SET @RunDate=GETDATE()
然后我在过程中使用它,因此所有更改(即使在多个表上)都具有完全相同的毫秒日期。我也更喜欢 dateModified 列允许空值并且没有默认值,当它被插入时,它已创建未修改,我将在实际修改时设置 dateModified。
然后使用:
UPDATE Customer
SET importantColumn=
,dateModified = @RunDate
WHERE ...
UPDATE CustomerPrice
SET importantColumn=
,dateModified = @RunDate
WHERE ...
【讨论】:
【参考方案4】:@astander 是对的,如果你想自动更新,你应该只使用更新触发器。我的更新触发器略有不同(我使用“插入”虚拟表)。这是一个应该适合您的架构(重命名,但您认为合适):
CREATE TRIGGER [CustomerDateModifiedTrigger] ON [dbo].[Customer]
FOR UPDATE
AS
UPDATE Customer
SET dateModified = GETDATE()
FROM Customer c
INNER JOIN inserted i ON c.customerID = i.customerID
【讨论】:
【参考方案5】:@Kronass,你根本不知道你在说什么!
timestamp 是 rowversion 数据类型的同义词,受数据类型同义词的行为影响。在 DDL 语句中,尽可能使用 rowversion 而不是 timestamp。有关详细信息,请参阅数据类型同义词 (Transact-SQL)。
Transact-SQL 时间戳数据类型不同于 ISO 标准中定义的时间戳数据类型。
不推荐使用时间戳语法。此功能将在 Microsoft SQL Server 的未来版本中删除。避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序。
rowversion (Transact-SQL) 是一种数据类型,可在数据库中公开自动生成的唯一二进制数。 rowversion 通常用作对表行进行版本标记的机制。存储大小为 8 个字节。 rowversion 数据类型只是一个递增的数字,不保留日期或时间。要记录日期或时间,请使用 datetime2 数据类型。
【讨论】:
【参考方案6】:1) 一定要为主键创建索引。 (我最近才发现这种类型的错误。)
2) 您可以使用一个 INSERT/UPDATE 触发器而不是单独的触发器,但代价是效率损失很小。如果 insert.DateCreated 为 null,则更新 Vals.DateCreated,否则更新 Vals.DateModified。
【讨论】:
【参考方案7】:SQL Server 中有一个数据类型叫做时间戳。每次修改行时都会跟踪行版本。 或者,如果您愿意,可以使用触发器并更改 ModifiedDate 列。
【讨论】:
时间跨度?在 SQL Server 中???真的?!?!??我认为 .NET 框架中有 TimeSpan - 但在 SQL Server 中肯定没有 - 至少我不知道 SQL Server 版本... 废话,我输入了错误的单词而不是时间戳,我错误地输入了时间跨度。以上是关于关于 DateCreated 和 DateModified 列的问题 - SQL Server的主要内容,如果未能解决你的问题,请参考以下文章