【问题标题】:How do I set a value for existing rows when creating a new timestamp column?创建新的时间戳列时如何为现有行设置值?
【发布时间】:2013-10-08 14:14:59
【问题描述】:

我有下表:

Study   id
Pepsi   1
Coke    2
Sprite  3

我需要在上表中添加一个新列timestamp。即,研究创建时间和日期将存储在此列中。我应该为现有行设置什么值?或者“时间戳”列是否应该只为新创建的行设置值?

我已使用以下查询来添加新列:

alter table Study add Timestamp datetime

【问题讨论】:

  • 这完全取决于您的要求。要么允许它们为空,要么选择一些默认值并将它们全部设置为该值(然后使列不可为空)
  • 警告: TIMESTAMP 是 SQL Server 中的 数据类型,该词是保留的 / 关键字。尽量避免使用它 - 使用其他名称(如 StudyCreated 或任何您喜欢的名称)作为您的列名!
  • 同意@marc_s - 拜托,拜托,请不要称这个专栏为timestamp - 就这样称呼它吧,比如StudyCreationTime,甚至只是CreationTime

标签: sql sql-server-2008


【解决方案1】:

没有办法告诉您应该为现有行设置什么值 - 这由您决定。如果您可以通过拼凑其他信息以某种方式检索创建时间,那么也许您可以一一完成,或者您可以将现有行留给NULL

为该列设置一个默认值,如 GETDATE(),并将其设置为 NOT NULL,强制所有现有行继承当前日期和时间 - 您将无法将它们设置回 @987654324 @。我非常反对使用像1900-01-01 这样的垃圾令牌值来表示未知,我也不相信修改代码以说“如果日期是 2013 年 10 月 8 日,那是因为我们只是没有知道。”所以我建议添加一个默认的NULLable 列:

ALTER TABLE dbo.Study ADD CreationTime DATETIME NULL DEFAULT CURRENT_TIMESTAMP;
GO

请注意,如果您将列保留为空,则 DEFAULT 约束仅在 DML 从未将其设置为 NULL 时才有用。例如,如果INSERT 语句明确将NULL 放置在那里,则忽略默认值。解决此问题的一种方法是使用触发器(就像您处理更新一样):

CREATE TRIGGER dbo.StudyCreationTime
ON dbo.Study
FOR INSERT 
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE s
    SET s.CreationTime = CURRENT_TIMESTAMP
    FROM dbo.Study AS s
    INNER JOIN inserted AS i
    ON s.StudyID = i.StudyID;
END
GO

【讨论】:

  • 我看到了你想要的最终结果,并认为这是一个很好的策略。我可能仍然会使用默认值而不是触发器。向可为空的列添加默认值不会更新现有行。
  • @Tim 触发器只是一个额外的建议,如果他们仍然希望列正确填充,即使某些 DML 使用显式 NULL 覆盖默认值。我已经重新措辞以使其更清楚。
  • 知道了,我从没想过这种情况。当您选择时,您是使用触发器、默认值还是应用程序来填充这些类型的列?
  • @Tim 我更喜欢 NOT NULL DEFAULT。我从不信任应用程序,除非必须,否则我不会使用触发器。通常当我使用触发器时,我会使用 INSTEAD OF 触发器,因为如果存在可能导致操作失败/回滚的业务逻辑,我不妨阻止它,而不是允许它发生然后回滚。
【解决方案2】:

我应该为以前的研究设置什么值

这必须由您的企业定义。这不需要技术答案,所以这里没有人可以告诉你什么是正确的。

我使用以下查询来添加新列:

alter table Study add Timestamp datetime

这可以正常工作,尽管这将允许空值。我可能建议将此列设为非空,添加默认值,并稍微更改列的名称,因为timestamp 是 SQL Server 中的保留字(与日期或时间关系不大的数据类型):

alter table Study add CreateDate datetime not null default current_timestamp;

请注意,这会将所有行设置为当前日期和时间,因此如果您有更准确的数据,您可能需要更新它们。或者,只需将列创建为可为空,现有行不会获得默认值,而是 null。

您可能必须做出的另一个选择是使用本地时间还是 UTC 时间(例如default getutcdate())。您可能希望使用与您的服务器或其他“CreateDate”列使用的时间相同的时间。

【讨论】:

  • 但是蒂姆,这会将所有现有行设置为当前时间,这是不正确的并且可能存在问题。
  • 非常正确。在提供最完整的答案和在其他答案之前点击提交以获得支持之间的平衡:我不知道。
猜你喜欢
  • 2013-06-20
  • 1970-01-01
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 1970-01-01
相关资源
最近更新 更多