暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

[ACDU 翻译] MySQL 11.2.5 TIMESTAMP 和 DATETIME 的自动初始化和更新

原创 由迪 2021-12-29
712

TIMESTAMPDATETIME列可以自动初始化并更新为当前日期和时间(即当前时间戳)。

对于表中的任何TIMESTAMPDATETIME列,您可以将当前时间戳指定为默认值、自动更新值或两者:

  • 自动初始化的列被设置为未指定列值的插入行的当前时间戳。
  • 当行中任何其他列的值从其当前值更改时,自动更新的列会自动更新为当前时间戳。如果所有其他列都设置为其当前值,则自动更新的列保持不变。要防止自动更新的列在其他列更改时更新,请将其显式设置为其当前值。要在其他列未更改时更新自动更新的列,请将其显式设置为应具有的值(例如,将其设置为 CURRENT_TIMESTAMP)。

此外,如果 explicit_defaults_for_timestamp 系统变量被禁用,您可以通过为其分配一个值来将任何TIMESTAMP(但不是 DATETIME)列初始化或更新 为当前日期和时间NULL,除非它已使用NULL属性定义为允许NULL值。

要指定自动属性,请在列定义中使用DEFAULT CURRENT_TIMESTAMPandON UPDATE CURRENT_TIMESTAMP子句。子句的顺序无关紧要。如果两者都出现在列定义中,则任一者都可以先出现。的任何同义词CURRENT_TIMESTAMP都与 具有相同的含义 CURRENT_TIMESTAMP。这是 CURRENT_TIMESTAMP()NOW()LOCALTIMELOCALTIME()LOCALTIMESTAMP,和 LOCALTIMESTAMP()

使用DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP特定于 TIMESTAMPDATETIME。该 DEFAULT子句还可用于指定常量(非自动)默认值(例如, DEFAULT 0DEFAULT '2000-01-01 00:00:00')。

笔记

以下示例使用DEFAULT 0,默认值可能会产生警告或错误,具体取决于启用了严格 SQL 模式还是 NO_ZERO_DATESQL 模式。请注意, TRADITIONALSQL 模式包括严格模式和 NO_ZERO_DATE. 请参阅 第 5.1.11 节,“服务器 SQL 模式”

TIMESTAMPDATETIME列定义可以为默认值和自动更新值指定当前时间戳,为一个而不是另一个,或两者都不指定。不同的列可以有不同的自动属性组合。以下规则描述了可能性:

  • 使用DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP,该列的默认值具有当前时间戳,并自动更新为当前时间戳。

    CREATE TABLE t1 ( ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
  • DEFAULT子句但没有ON UPDATE CURRENT_TIMESTAMP子句时,列具有给定的默认值并且不会自动更新到当前时间戳。

    默认值取决于 DEFAULT子句是指定 CURRENT_TIMESTAMP值还是常量值。使用CURRENT_TIMESTAMP,默认为当前时间戳。

    CREATE TABLE t1 ( ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP, dt DATETIME DEFAULT CURRENT_TIMESTAMP );

    对于常量,默认值为给定值。在这种情况下,该列根本没有自动属性。

    CREATE TABLE t1 ( ts TIMESTAMP DEFAULT 0, dt DATETIME DEFAULT 0 );
  • 使用ON UPDATE CURRENT_TIMESTAMP 子句和常量DEFAULT子句,列会自动更新为当前时间戳并具有给定的常量默认值。

    CREATE TABLE t1 ( ts TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP, dt DATETIME DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP );
  • ON UPDATE CURRENT_TIMESTAMP 子句但没有DEFAULT子句时,列会自动更新为当前时间戳,但没有默认值的当前时间戳。

    这种情况下的默认值是类型相关的。 TIMESTAMP除非使用NULL属性定义,否则默认值为 0 ,在这种情况下,默认值为NULL

    CREATE TABLE t1 ( ts1 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- default 0 ts2 TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP -- default NULL );

    DATETIME有一个默认值, NULL除非用NOT NULL属性定义,在这种情况下,默认值是 0。

    CREATE TABLE t1 ( dt1 DATETIME ON UPDATE CURRENT_TIMESTAMP, -- default NULL dt2 DATETIME NOT NULL ON UPDATE CURRENT_TIMESTAMP -- default 0 );

TIMESTAMPDATETIME列没有自动属性,除非明确指定,但这个例外:如果 explicit_defaults_for_timestamp 系统变量被禁用,则第一 TIMESTAMP列具有两者 DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP如果没有明确指定。要取消第一TIMESTAMP列的自动属性 ,请使用以下策略之一:

  • 启用 explicit_defaults_for_timestamp 系统变量。在这种情况下,指定自动初始化和更新的DEFAULT CURRENT_TIMESTAMPandON UPDATE CURRENT_TIMESTAMP子句可用,但不会分配给任何TIMESTAMP 列,除非明确包含在列定义中。
  • 或者,如果 explicit_defaults_for_timestamp 已禁用,请执行以下任一操作:
    • 使用DEFAULT 指定常量默认值的子句定义列。
    • 指定NULL属性。这也会导致列允许NULL 值,这意味着您无法通过将列设置为 来分配当前时间戳 NULL。分配 NULL将列设置为 NULL,而不是当前时间戳。要分配当前时间戳,请将列设置为 CURRENT_TIMESTAMP或 同义词,例如NOW()

考虑这些表定义:

CREATE TABLE t1 ( ts1 TIMESTAMP DEFAULT 0, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); CREATE TABLE t3 ( ts1 TIMESTAMP NULL DEFAULT 0, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);

这些表具有以下属性:

  • 在每个表定义中,第一 TIMESTAMP列没有自动初始化或更新。
  • 这些表在ts1列处理NULL值的方式上有所不同。对于 t1, ts1is NOT NULL并为其分配一个值 NULL将其设置为当前时间戳。对于t2and t3ts1允许NULL并为其分配一个值 将其NULL设置为 NULL
  • t2t3的默认值不同ts1。对于 t2,ts1被定义为 permit NULL,因此默认值也是 NULL在没有显式DEFAULT子句的情况下 。对于 t3ts1允许 NULL但有一个明确的默认值 0。

如果TIMESTAMPor DATETIME列定义在任何地方包含明确的小数秒精度值,则必须在整个列定义中使用相同的值。这是允许的:

CREATE TABLE t1 ( ts TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) );

这是不允许的:

CREATE TABLE t1 ( ts TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(3) );

TIMESTAMP 初始化和 NULL 属性

如果 explicit_defaults_for_timestamp 系统变量被禁用, TIMESTAMP默认情况下列是 NOT NULL,不能包含 NULL值,并且分配 NULL分配当前时间戳。要允许TIMESTAMP列包含 NULL,请使用NULL属性显式声明它 。在这种情况下,NULL除非被DEFAULT指定不同默认值的子句覆盖,否则默认值也会变为。DEFAULT NULL可用于显式指定NULL为默认值。(对于TIMESTAMP 未使用NULL属性声明的列, DEFAULT NULL无效。)如果 TIMESTAMP列允许 NULL值,分配 NULL将其设置为NULL,而不是当前时间戳。

下表包含多个 TIMESTAMP允许NULL值的列 :

CREATE TABLE t ( ts1 TIMESTAMP NULL DEFAULT NULL, ts2 TIMESTAMP NULL DEFAULT 0, ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP );

TIMESTAMP允许NULL值 的列 在插入时不会采用当前时间戳,除非在以下条件之一下:

换句话说,TIMESTAMP 定义为允许NULL值自动初始化的列仅在其定义包括 DEFAULT CURRENT_TIMESTAMP

CREATE TABLE t (ts TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP);

如果TIMESTAMP列允许 NULL值但其定义不包括DEFAULT CURRENT_TIMESTAMP,则必须显式插入与当前日期和时间对应的值。假设表t1t2具有这些定义:

CREATE TABLE t1 (ts TIMESTAMP NULL DEFAULT '0000-00-00 00:00:00'); CREATE TABLE t2 (ts TIMESTAMP NULL DEFAULT NULL);

要将TIMESTAMP任一表中的列设置为插入时的当前时间戳,请明确为其分配该值。例如:

INSERT INTO t2 VALUES (CURRENT_TIMESTAMP); INSERT INTO t1 VALUES (NOW());

如果explicit_defaults_for_timestamp 启用了 系统变量,则 TIMESTAMPNULL仅在使用NULL属性声明时才允许 值 。此外, TIMESTAMP列不允许分配NULL以分配当前时间戳,无论是使用NULLor NOT NULL属性声明的。要分配当前时间戳,请将列设置为 CURRENT_TIMESTAMP或 同义词,例如NOW()

最后修改时间:2021-12-29 16:31:55
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论