添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

1.TIMESTAMP和DATETIME的自动初始化和更新

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

对于表中的任何TIMESTAMP或DATETIME列,可以将当前时间戳指定为默认值、自动更新值或同时指定这两个值:

●当向表中插入新的记录时,如果没有为自动初始化列指定值,该列会设置为当前时间戳。

●当行中任何其他列的值更改时,自动更新列将自动更新为当前时间戳。如果所有其他列都设置为其当前值,则自动更新的列将保持不变。若要防止在其他列更改时自动更新列,请将其显式设置为它的当前值。要更新自动更新列(即使其他列没有更改),请显式将其设置为应有的值(例如,将其设置为CURRENT_TIMESTAMP)。

此外,如果已禁用explicit_defaults_for_timestamp系统变量,则可以通过为任何TIMESTAMP(但不是DATETIME)列分配空值(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。

TIMESTAMP或DATETIME列定义可以为默认值和自动更新值指定当前时间戳,也可以仅为一个值指定当前时间戳,还可以都不指定。不同的列可以有不同的自动属性组合。以下规则描述了这些可能性:

● 具有DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP属性,列的默认值和自动更新值都是当期时间戳。

●如果有DEFAULT子句,但没有ON UPDATE CURRENT_TIMESTAMP子句,则该列具有给定的默认值,但不会自动更新为当前时间戳。

默认值取决于DEFAULT子句指定的是CURRENT_TIMESTAMP还是常量值。如果指定的是CURRENT_TIMESTAMP,默认值是当前时间戳。

如果指定的是常量,默认值为给定值。在这种情况下,列根本没有自动属性。

●使用ON UPDATE CURRENT_TIMESTAMP子句和常量DEFAULT子句,该列将自动更新为当前时间戳并具有给定的常量默认值。

●如果有ON UPDATE CURRENT_TIMESTAMP子句但没有DEFAULT子句,则该列将自动更新为当前时间戳,但其默认值不是当前时间戳。

在这种情况下,默认值是依赖于类型的。TIMESTAMP的默认值为0,除非使用NULL属性定义,这时默认值为NULL。
MySQL数据类型 - 日期和时间类型(2)

DATETIME的默认值为NULL,除非使用NOT NULL属性定义,这时默认值为0。
MySQL数据类型 - 日期和时间类型(2)

除非显式指定,否则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,而不是当前时间戳。要分配当前时间戳,请将列设置为CURRENT_TIMESTAMP或NOW()等同义词。

请考虑以下表定义:
MySQL数据类型 - 日期和时间类型(2)

这些表具有以下属性:

●在每个表定义中,第一个TIMESTAMP列没有自动初始化或更新。

●这些表在ts1列处理NULL值的方式上有所不同。对于t1,ts1不为空,并且将其赋值为空会将其设置为当前时间戳。对于t2和t3,ts1允许NULL,并将其赋值为NULL就是将其设置为NULL。

●t2和t3表ts1的默认值不同。对于t2,ts1被定义为允许NULL,因此在没有显式DEFAULT子句的情况下,缺省值也是NULL。对于t3,ts1允许空值,但显式默认值为0。

如果TIMESTAMP或DATETIME列定义包含显式小数秒精度值,则必须在整个列定义中使用相同的值。

以下定义是允许的:

以下定义是不允许的:

TIMESTAMP初始化和NULL属性

如果禁用explicit_defaults_for_timestamp系统变量,则默认情况下TIMESTAMP列NOT NULL,不能包含空值,并且赋值为NULL将指定当前时间戳。若要允许TIMESTAMP列包含NULL,请使用NULL属性显式声明它。在这种情况下,默认值将为NULL,除非使用DEFAULT子句指定其他默认值。可以使用DEFAULT NULL显式指定NULL作为默认值。(对于没有使用NULL属性声明的TIMESTAMP列,DEFAULT NULL无效。)如果TIMESTAMP列允许NULL值,则将值设置为NULL,值就是NULL,而不是当前时间戳。

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

允许空值的TIMESTAMP列在插入时不接受当前时间戳,除非有下列条件:

●它的默认值被定义为CURRENT_TIMESTAMP,并且没有为列指定值

●CURRENT_TIMESTAMP或其任何同义词(如NOW())显式插入到列中

换句话说,仅当定义包含DEFAULT CURRENT_TIMESTAMP时,定义允许NULL值的TIMESTAMP列才会自动初始化:

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

MySQL数据类型 - 日期和时间类型(2)
要将任一表中的TIMESTAMP列设置为插入时使用当前TIMESTAMP,请显式地为其指定该值。例如:

如果启用explicit_defaults_for_timestamp系统变量,则仅当使用NULL属性声明时,TIMESTAMP列才允许空值。此外,无论是否使用NULL或者NOT NULL属性,TIMESTAMP列不允许通过分配NULL值来分配当前时间戳。要分配当前时间戳,请将列设置为CURRENT_TIMESTAMP或NOW()等同义词。

英文官网地址:
https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html