TIMESTAMP
和 DATETIME
列可以自动初始化和更新到当前日期和时间(即当前时间戳)。
对于任何 TIMESTAMP
或 DATETIME
列,可以将当前时间戳作为默认值、自动更新值或两者。
-
自动初始化的列将在插入行时指定无值时设置为当前时间戳。
-
自动更新的列将在其他列的值更改时自动更新到当前时间戳。如果其他列保持不变,自动更新的列将保持不变。要防止自动更新的列在其他列更改时更新,请明确设置其当前值。要在其他列不变时更新自动更新的列,请明确设置其应有的值(例如,设置为
CURRENT_TIMESTAMP
)。
此外,如果 explicit_defaults_for_timestamp
系统变量被禁用,可以通过将其设置为 NULL
值来初始化或更新任何 TIMESTAMP
(但不是 DATETIME
)列,除非它被定义为允许 NULL
值。
要指定自动属性,请在列定义中使用 DEFAULT CURRENT_TIMESTAMP
和 ON UPDATE 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
列没有自动初始化或更新。 -
这些表在处理
NULL
值方面有所不同。t1
中的ts1
列不是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()
被明确插入该列
换言之,允许 NULL
值的 TIMESTAMP
列只有在其定义中包含 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
系统变量,TIMESTAMP
列仅允许在声明了NULL
属性时具有空值。此外,TIMESTAMP
列不允许将空值分配给当前时间戳,无论是否声明了NULL
或NOT NULL
属性。要分配当前时间戳,请将列设置为CURRENT_TIMESTAMP
或同义词,如NOW()
。