Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  Automatic Initialization and Updating for TIMESTAMP and DATETIME

13.2.5 TIMESTAMP 和 DATETIME 的自动初始化和更新

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

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

  • 一个自动初始化的列将在插入行中设置为当前时间戳,如果插入行未指定该列的值。

  • 一个自动更新的列将在任何其他列的值发生变化时自动更新到当前时间戳。一个自动更新的列将保持不变,如果所有其他列保持不变。要防止自动更新的列在其他列变化时更新,请明确地将其设置为当前值。要在其他列不变化时更新自动更新的列,请明确地将其设置为所需的值(例如,将其设置为 CURRENT_TIMESTAMP)。

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

要指定自动属性,请使用 DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP take in 列定义中。这些子句的顺序无关紧要。如果在列定义中同时出现这两个子句,可以出现的顺序无关紧要。任何 CURRENT_TIMESTAMP 的同义词都具有相同的含义,这些同义词是 CURRENT_TIMESTAMPNOW()LOCALTIMELOCALTIME()LOCALTIMESTAMPLOCALTIMESTAMP()

使用 DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP 是专门为TIMESTAMPDATETIME 设计的。 DEFAULT take also can be used to specify a constant (nonautomatic) default value (for example, DEFAULT 0 or DEFAULT '2000-01-01 00:00:00').

Note

以下示例使用 DEFAULT 0,一个可以根据是否启用严格 SQL 模式或 NO_ZERO_DATE SQL 模式产生警告或错误的默认值。注意 TRADITIONAL SQL 模式包括严格模式和 NO_ZERO_DATE。请参阅第7.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 take 但没有 ON UPDATE CURRENT_TIMESTAMP take,该列具有给定的默认值,但不自动更新到当前时间戳。

    默认值取决于 DEFAULT take 是否指定 CURRENT_TIMESTAMP 或常量值。使用 CURRENT_TIMESTAMP,默认值为当前时间戳。

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

    使用常量,default 是给定的值。在这种情况下,该列没有自动属性。

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

    CREATE TABLE t1 (
      ts TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP,
      dt DATETIME DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP
    );
  • 使用 ON UPDATE CURRENT_TIMESTAMP take 但没有 DEFAULT take,该列自动更新到当前时间戳,但不具有当前时间戳为其默认值。

    在这种情况下,default 取决于类型。 TIMESTAMP 的默认值为 0,除非定义了 NULL 属性,在这种情况下,default 是 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 属性,在这种情况下,default 是 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_TIMESTAMPON 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 值。对于 t1ts1NOT NULL,将其设置为 NULL 将设置为当前时间戳。对于 t2t3ts1 允许 NULL,将其设置为 NULL 将设置为 NULL

  • t2t3ts1 的默认值上有所不同。对于 t2ts1 允许 NULL,因此在缺省情况下,ts1 的默认值也为 NULL,除非使用 DEFAULT 子句。对于 t3ts1 允许 NULL,但其默认值为 0。

如果 TIMESTAMPDATETIME 列定义包含明确的分秒精度值-anywhere,该值必须在整个列定义中保持一致。这是允许的:

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)
);

如果 explicit_defaults_for_timestamp 系统变量被禁用,TIMESTAMP 列默认情况下是 NOT NULL,不能包含 NULL 值,并将 NULL 分配给当前时间戳。要允许 TIMESTAMP 列包含 NULL,请明确声明它具有 NULL 属性。在这种情况下,缺省值也将变为 NULL,除非使用 DEFAULT 子句指定不同的缺省值。可以使用 DEFAULT NULL 来明确指定 NULL 作为缺省值。 (对于未使用 NULL 属性声明的 TIMESTAMP 列,DEFAULT NULL 无效。) 如果 TIMESTAMP 列允许 NULL 值,将 NULL 分配给它,而不是当前时间戳。

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

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

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

换言之,一个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系统变量启用,TIMESTAMP列允许NULL值,只要声明了NULL属性。同时,TIMESTAMP列不允许将当前时间戳分配给NULL,无论声明了NULLNOT NULL属性。要分配当前时间戳,设置列为CURRENT_TIMESTAMP或同义词,如NOW()