TIMESTAMP
和 DATETIME
列可以自动初始化和更新为当前日期和时间(即当前时间戳)。
对于表中的任何 TIMESTAMP
或 DATETIME
列,您都可以将当前时间戳指定为默认值、自动更新值或两者。
对于插入的未指定列值的行,自动初始化的列将设置为当前时间戳。
当行的任何其他列的值从其当前值更改时,自动更新的列会自动更新为当前时间戳。如果所有其他列都设置为其当前值,则自动更新的列保持不变。要防止自动更新的列在其他列更改时更新,请显式将其设置为其当前值。要更新自动更新的列,即使其他列没有更改,请显式将其设置为它应该具有的值(例如,将其设置为
CURRENT_TIMESTAMP
)。
此外,如果 explicit_defaults_for_timestamp
系统变量已禁用,则可以通过将任何 TIMESTAMP
(但不是 DATETIME
)列分配为 NULL
值来将其初始化或更新为当前日期和时间,除非它已定义为具有 NULL
属性以允许 NULL
值。
要指定自动属性,请在列定义中使用 DEFAULT CURRENT_TIMESTAMP
和 ON UPDATE CURRENT_TIMESTAMP
子句。子句的顺序无关紧要。如果在列定义中都存在,则任何一个都可以先出现。CURRENT_TIMESTAMP
的任何同义词都与 CURRENT_TIMESTAMP
具有相同的含义。这些是 CURRENT_TIMESTAMP()
、NOW()
、LOCALTIME
、LOCALTIME()
、LOCALTIMESTAMP
和 LOCALTIMESTAMP()
。
DEFAULT CURRENT_TIMESTAMP
和 ON UPDATE CURRENT_TIMESTAMP
的使用特定于 TIMESTAMP
和 DATETIME
。DEFAULT
子句也可以用于指定常量(非自动)默认值(例如,DEFAULT 0
或 DEFAULT '2000-01-01 00:00:00'
)。
以下示例使用 DEFAULT 0
,这是一个默认值,它可能会生成警告或错误,具体取决于是否启用了严格的 SQL 模式或 NO_ZERO_DATE
SQL 模式。请注意,TRADITIONAL
SQL 模式包括严格模式和 NO_ZERO_DATE
。请参见 第 7.1.11 节,“服务器 SQL 模式”。
TIMESTAMP
或 DATETIME
列定义可以为默认值和自动更新值都指定当前时间戳,也可以为其中一个指定,也可以为两者都不指定。不同的列可以具有自动属性的不同组合。以下规则描述了可能性
使用
DEFAULT CURRENT_TIMESTAMP
和ON 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
的默认值为 0,除非定义为具有NULL
属性,在这种情况下,默认值为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 );
TIMESTAMP
和 DATETIME
列没有自动属性,除非它们被显式指定,但有一个例外:如果 explicit_defaults_for_timestamp
系统变量已禁用,则第一个 TIMESTAMP
列都具有 DEFAULT CURRENT_TIMESTAMP
和 ON UPDATE CURRENT_TIMESTAMP
,即使两者都没有被显式包含。要抑制第一个 TIMESTAMP
列的自动属性,请使用以下策略之一
启用
explicit_defaults_for_timestamp
系统变量。在这种情况下,指定自动初始化和更新的DEFAULT CURRENT_TIMESTAMP
和ON 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
,ts1
为NOT NULL
,并且为其分配NULL
值会将其设置为当前时间戳。对于t2
和t3
,ts1
允许NULL
,并且为其分配NULL
值会将其设置为NULL
。t2
和t3
在ts1
的默认值方面有所不同。对于t2
,ts1
被定义为允许NULL
,因此在没有显式DEFAULT
子句的情况下,默认值也是NULL
。对于t3
,ts1
允许NULL
,但具有 0 的显式默认值。
如果 TIMESTAMP
或 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
作为默认值。(对于没有使用 NULL
属性声明的 TIMESTAMP
列,DEFAULT NULL
是无效的。)如果 TIMESTAMP
列允许 NULL
值,则分配 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
列在插入时 不会 获取当前时间戳,除非满足以下条件之一
它的默认值被定义为
CURRENT_TIMESTAMP
,并且没有为该列指定值CURRENT_TIMESTAMP
或其任何同义词(如NOW()
)被显式插入到该列中
换句话说,如果 TIMESTAMP
列被定义为允许 NULL
值,则只有在它的定义包含 DEFAULT CURRENT_TIMESTAMP
时,它才会自动初始化
CREATE TABLE t (ts TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP);
如果 TIMESTAMP
列允许 NULL
值,但它的定义不包含 DEFAULT CURRENT_TIMESTAMP
,则您必须显式插入与当前日期和时间相对应的值。假设表 t1
和 t2
具有以下定义
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
系统变量被启用,则只有在使用 NULL
属性声明时,TIMESTAMP
列才允许 NULL
值。此外,无论使用 NULL
或 NOT NULL
属性声明,TIMESTAMP
列都不允许分配 NULL
来分配当前时间戳。要分配当前时间戳,请将该列设置为 CURRENT_TIMESTAMP
或其同义词,如 NOW()
。