### 11.2.5 TIMESTAMP 和 DATETIME 的自动初始化和更新

[](<>)

[`时间戳`](datetime.html)和[`约会时间`](datetime.html)列可以自动初始化并更新为当前日期和时间（即当前时间戳）。

对于任何[`时间戳`](datetime.html)要么[`约会时间`](datetime.html)表中的列，您可以将当前时间戳指定为默认值、自动更新值或两者：

-   自动初始化的列设置为插入的行的当前时间戳，这些行没有为该列指定值。

-   当行中任何其他列的值从其当前值更改时，自动更新的列会自动更新为当前时间戳。如果所有其他列都设置为其当前值，则自动更新的列保持不变。要防止自动更新的列在其他列更改时更新，请将其显式设置为其当前值。要更新自动更新的列，即使其他列没有更改，请将其显式设置为应具有的值（例如，将其设置为[`CURRENT_TIMESTAMP`](date-and-time-functions.html#function_current-timestamp)）。

    此外，如果[`显式默认值for_timestamp`](server-system-variables.html#sysvar_explicit_defaults_for_timestamp)系统变量被禁用，您可以初始化或更新任何[`时间戳`](datetime.html)（但不是`约会时间`) 列分配给当前日期和时间`空值`值，除非它已与`空值`允许的属性`空值`价值观。

    要指定自动属性，请使用`默认 CURRENT_TIMESTAMP`和`ON UPDATE CURRENT_TIMESTAMP`列定义中的子句。子句的顺序无关紧要。如果两者都存在于列定义中，则任何一个都可以先出现。的任何同义词[`CURRENT_TIMESTAMP`](date-and-time-functions.html#function_current-timestamp)具有相同的含义[`CURRENT_TIMESTAMP`](date-and-time-functions.html#function_current-timestamp).这些是[`CURRENT_TIMESTAMP()`](date-and-time-functions.html#function_current-timestamp),[`现在（）`](date-and-time-functions.html#function_now),[`当地时间`](date-and-time-functions.html#function_localtime),[`当地时间（）`](date-and-time-functions.html#function_localtime),[`本地时间戳`](date-and-time-functions.html#function_localtimestamp)， 和[`本地时间戳（）`](date-and-time-functions.html#function_localtimestamp).

    用于`默认 CURRENT_TIMESTAMP`和`ON UPDATE CURRENT_TIMESTAMP`特定于[`时间戳`](datetime.html)和[`约会时间`](datetime.html).这`默认`子句也可用于指定常量（非自动）默认值（例如，`默认0`要么`默认“2000-01-01 00:00:00”`）。

笔记

以下示例使用`默认0`, 一个默认值，根据是严格 SQL 模式还是[`NO_ZERO_DATE`](sql-mode.html#sqlmode_no_zero_date)SQL 模式已启用。请注意，[`传统的`](sql-mode.html#sqlmode_traditional)SQL 模式包括严格模式和[`NO_ZERO_DATE`](sql-mode.html#sqlmode_no_zero_date).看[第 5.1.11 节，“服务器 SQL 模式”](sql-mode.html).

[`时间戳`](datetime.html)要么[`约会时间`](datetime.html)列定义可以为默认值和自动更新值指定当前时间戳，一个但不指定另一个，或者两者都不指定。不同的列可以有不同的自动属性组合。以下规则描述了这些可能性：

-   既`默认 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
    );
    ```

-   带一个`默认`条款但没有`ON UPDATE CURRENT_TIMESTAMP`子句，该列具有给定的默认值，并且不会自动更新为当前时间戳。

    默认值取决于是否`默认`条款规定`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`子句和常数`默认`子句，该列会自动更新为当前时间戳，并具有给定的常量默认值。

    ```
    CREATE TABLE t1 (
      ts TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP,
      dt DATETIME DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP
    );
    ```

-   与`ON UPDATE CURRENT_TIMESTAMP`条款但没有`默认`子句时，该列会自动更新为当前时间戳，但没有当前时间戳作为其默认值。

    在这种情况下，默认值取决于类型。[`时间戳`](datetime.html)除非用`空值`属性，在这种情况下，默认值为`空值`.

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

    [`约会时间`](datetime.html)有一个默认值`空值`除非用`非空`属性，在这种情况下，默认值为 0。

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

[`时间戳`](datetime.html)和[`约会时间`](datetime.html)除非明确指定列，否则列没有自动属性，但有以下例外：如果[`显式默认值for_timestamp`](server-system-variables.html#sysvar_explicit_defaults_for_timestamp)系统变量被禁用时，*第一的* [`时间戳`](datetime.html)列都有`默认 CURRENT_TIMESTAMP`和`ON UPDATE CURRENT_TIMESTAMP`如果两者都没有明确指定。抑制第一个的自动属性[`时间戳`](datetime.html)列，使用以下策略之一：

-   启用[`显式默认值for_timestamp`](server-system-variables.html#sysvar_explicit_defaults_for_timestamp)系统变量。在这种情况下，`默认 CURRENT_TIMESTAMP`和`ON UPDATE CURRENT_TIMESTAMP`指定自动初始化和更新的子句可用，但未分配给任何[`时间戳`](datetime.html)列，除非明确包含在列定义中。

-   或者，如果[`显式默认值for_timestamp`](server-system-variables.html#sysvar_explicit_defaults_for_timestamp)已禁用，请执行以下任一操作：

    -   用 a 定义列`默认`指定常量默认值的子句。

    -   指定`空值`属性。这也导致该列允许`空值`值，这意味着您不能通过将列设置为来分配当前时间戳`空值`.分配`空值`将列设置为`空值`，而不是当前时间戳。要分配当前时间戳，请将列设置为[`CURRENT_TIMESTAMP`](date-and-time-functions.html#function_current-timestamp)或同义词，例如[`现在（）`](date-and-time-functions.html#function_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);
```

这些表具有以下属性：

-   在每个表定义中，第一个[`时间戳`](datetime.html)列没有自动初始化或更新。

-   这些表的不同之处在于`ts1`柱柄`空值`价值观。为了`t1`,`ts1`是`非空`并为其赋值`空值`将其设置为当前时间戳。为了`t2`和`t3`,`ts1`许可证`空值`并为其赋值`空值`将其设置为`空值`.

-   `t2`和`t3`默认值不同`ts1`.为了`t2`,`ts1`被定义为允许`空值`，所以默认也是`空值`在没有明确的`默认`条款。为了`t3`,`ts1`许可证`空值`但显式默认值为 0。

    如果一个[`时间戳`](datetime.html)要么[`约会时间`](datetime.html)列定义在任何地方都包含显式的小数秒精度值，必须在整个列定义中使用相同的值。这是允许的：


```
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 属性

如果[`显式默认值for_timestamp`](server-system-variables.html#sysvar_explicit_defaults_for_timestamp)系统变量被禁用，[`时间戳`](datetime.html)默认情况下，列是`非空`, 不能包含`空值`值和赋值`空值`分配当前时间戳。允许一个[`时间戳`](datetime.html)要包含的列`空值`, 用`空值`属性。在这种情况下，默认值也变为`空值`除非被覆盖`默认`指定不同默认值的子句。`默认空`可用于显式指定`空值`作为默认值。（为一个[`时间戳`](datetime.html)未与声明的列`空值`属性，`默认空`无效。）如果[`时间戳`](datetime.html)列许可证`空值`值，赋值`空值`将其设置为`空值`，而不是当前时间戳。

下表包含几个[`时间戳`](datetime.html)允许的列`空值`价值观：

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

一种[`时间戳`](datetime.html)允许的列`空值`价值观确实*不是*在插入时采用当前时间戳，但以下情况之一除外：

-   其默认值定义为[`CURRENT_TIMESTAMP`](date-and-time-functions.html#function_current-timestamp)并且没有为该列指定值

-   [`CURRENT_TIMESTAMP`](date-and-time-functions.html#function_current-timestamp)或其任何同义词，例如[`现在（）`](date-and-time-functions.html#function_now)被显式插入到列中

    换句话说，一个[`时间戳`](datetime.html)定义为允许的列`空值`values 仅在其定义包括时自动初始化`默认 CURRENT_TIMESTAMP`：


```
CREATE TABLE t (ts TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP);
```

如果[`时间戳`](datetime.html)列许可证`空值`值，但其定义不包括`默认 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);
```

设置[`时间戳`](datetime.html)任一表中的列到插入时的当前时间戳，显式为其分配该值。例如：

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

如果[`显式默认值for_timestamp`](server-system-variables.html#sysvar_explicit_defaults_for_timestamp)系统变量已启用，[`时间戳`](datetime.html)列允许`空值`仅当使用`空值`属性。还，[`时间戳`](datetime.html)列不允许分配`空值`分配当前时间戳，无论是否用`空值`要么`非空`属性。要分配当前时间戳，请将列设置为[`CURRENT_TIMESTAMP`](date-and-time-functions.html#function_current-timestamp)或同义词，例如[`现在（）`](date-and-time-functions.html#function_now).
