7

是否有一种特殊的方法可以在 MS Sql Server 表中声明 DateCreated 列,以便在创建时自动使用适当的时间戳填充它?

或者..我是否必须在手动进行查询时向它提供日期时间?

4

5 回答 5

18

默认值有两个主要缺点。

  • 如果插入语句为列指定了一个值,则不使用默认值。
  • 该列可以随时更新。

这意味着您不能确定这些值没有在您的控制之外进行修改。

如果您想要真正的数据完整性(以便确定行中的日期是创建日期),则需要使用触发器。

将列设置为当前日期的插入触发器和防止更改该列(或更准确地说,将其设置为其当前值)的更新触发器是实现 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
于 2009-02-17T05:10:36.980 回答
11

您可以将列的默认值设置为“getdate()”

于 2009-02-17T04:59:20.953 回答
2

我们在 CreatedDate 上有默认值,并且不使用触发器强制执行

有时我们想明确设置日期 - 例如,如果我们从其他来源导入数据。

存在应用程序错误可能会弄乱 CreateDate 的风险,或者对此感到不满的 DBA(我们没有非 DBA 直接连接到我们的 DB)

我想您可能会在 CreateDate 上设置列级权限。

折衷办法可能是让 INSERT TRIGGER 在 1:1 表中创建一行,以便该列位于主表之外。第二个表可以具有 SELECT 权限,其中主表具有 UPDATE 权限,因此不需要 UPDATE 触发器来防止对 CreateDate 的更改 - 这将在正常更新行时删除一些“权重”。

我想你可以在第二个表上有一个 UPDATE/DELETE 触发器来防止更改(在正常情况下永远不会执行,所以“轻量级”)

虽然有点痛苦,但拥有额外的表......可能有一个表用于所有 CreateDates - TableName,PK,CreateDate。大多数数据库架构师会讨厌这样......

于 2009-02-17T11:31:26.330 回答
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 
于 2009-02-17T08:52:40.173 回答
1

设置默认值是不够的,你应该添加一个触发器来防止更新:

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]))
于 2020-01-17T08:30:39.293 回答