是否有一种特殊方法可以在MS Sql Server表中声明DateCreated列,以便在创建时自动用适当的时间戳填充它?
或者..我在手动执行查询时是否必须提供日期时间?
答案 0 :(得分:16)
默认值有两个主要缺点。
这意味着您无法确定这些值未在您的控制范围之外进行修改。
如果您想要真正的数据完整性(以便确定行中的日期是创建日期),则需要使用触发器。
用于将列设置为当前日期的插入触发器和用于防止更改该列的更新触发器(或者更准确地说,将其设置为当前值)是实现DateCreated列的方法。
将列设置为当前日期的插入和更新触发器是实现DateModified列的方法。
(从用户Gabriel编辑 - 这是我尝试按照描述实现这一点 - 我不是100%确定它是正确的但我希望OP审核它......):
CREATE TRIGGER [dbo].[tr_Affiliate_IU]
ON [dbo].[Affiliate]
AFTER INSERT, UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Get the current date.
DECLARE @getDate DATETIME = GETDATE()
-- Set the initial values of date_created and date_modified.
UPDATE
dbo.Affiliate
SET
date_created = @getDate
FROM
dbo.Affiliate A
INNER JOIN INSERTED I ON A.id = I.id
LEFT OUTER JOIN DELETED D ON I.id = D.id
WHERE
D.id IS NULL
-- Ensure the value of date_created does never changes.
-- Update the value of date_modified to the current date.
UPDATE
dbo.Affiliate
SET
date_created = D.date_created
,date_modified = @getDate
FROM
dbo.Affiliate A
INNER JOIN INSERTED I ON A.id = I.id
INNER JOIN DELETED D ON I.id = D.id
END
答案 1 :(得分:10)
您可以将列的默认值设置为“getdate()”
答案 2 :(得分:2)
我们在CreatedDate上有DEFAULT,并且不强制使用触发器
有时我们要明确设置日期 - 例如如果我们从其他来源导入数据。
存在一个风险,即Application Bug可能会混淆CreateDate,或者是一个心怀不满的DBA(我们没有非DBA直接连接到我们的数据库)
我想你可以在CreateDate上设置列级权限。
中途宿舍可能是让一个INSERT TRIGGER在1:1表中创建一行,这样该列就在主表之外。第二个表可以具有SELECT权限,其中主表具有UPDATE权限,因此不需要UPDATE触发器来阻止对CreateDate的更改 - 这会在正常更新行时删除一些“权重”。
我想你可以在第二个表上有一个UPDATE / DELETE触发器以防止改变(在正常情况下永远不会执行,所以“轻量级”)
虽然有额外的表可能会有一点痛苦......可能有一个表用于所有CreateDates - TableName,PK,CreateDate。大多数数据库架构师都会讨厌这个......
答案 3 :(得分:1)
当然是。
以下是您的实例。
Create table #TableName
(
ID INT IDENTITY(1,1) PRIMARY KEY,
CreatedDate DATETIME NOT NULL DEFAULT GETDATE(),
SomeDate VARCHAR(100)
)
INSERT INTO #TableName (SomeDate)
SELECT 'Some data one' UNION ALL SELECT 'some data two'
SELECT * FROM #TableName
DROP TABLE #TableName
答案 4 :(得分:0)
仅设置默认值还不够,您应该添加触发器以防止更新:
CREATE TRIGGER UpdateRecord ON my_table
AFTER UPDATE AS UPDATE my_table
SET [CreatedDate] = ((SELECT TOP 1 [CreatedDate] FROM Deleted d where d.[id]=[id]))