【问题标题】:Invalid default value for timestamp column时间戳列的默认值无效
【发布时间】:2016-11-05 14:05:04
【问题描述】:

我找不到为什么这在 MySQL 5.7 中无效(用 5.7.16 测试)

CREATE TABLE TEST_TABLE (ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
INSERT INTO TEST_TABLE() VALUES ();
DROP TEMPORARY TABLE IF EXISTS TMP_TEST;
CREATE TEMPORARY TABLE TMP_TEST SELECT * FROM (SELECT ts FROM TEST_TABLE) wrap;

我得到这个:错误代码:1067。“ts”的默认值无效

是我遗漏了什么还是 mysql 的错误?

【问题讨论】:

  • 为我工作...
  • 不知道为什么需要TEMPORARY TABLE TMP_TEST,因为你没有使用。但是你错过了一个分号;
  • 假设它们实际上是作为 4 个不同的语句处理的,CREATE TEMPORARY TABLE TMP_TEST 触发 一个表必须至少有 1 列。这是真实的代码还是只是一个简化的测试用例?
  • 不漏分号,第 4 行和第 5 行是一个语句

标签: mysql stored-procedures timestamp


【解决方案1】:

我无法重现该问题。

mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.16    |
+-----------+
1 row in set (0,00 sec)

mysql> CREATE TABLE TEST_TABLE (ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0,00 sec)

mysql> INSERT INTO TEST_TABLE() VALUES ();
Query OK, 1 row affected (0,00 sec)

mysql> SELECT * FROM (SELECT ts FROM TEST_TABLE) wrap;
+---------------------+
| ts                  |
+---------------------+
| 2016-11-04 00:00:01 |
+---------------------+
1 row in set (0,00 sec)

mysql> DROP TEMPORARY TABLE IF EXISTS TMP_TEST;
Query OK, 0 rows affected, 1 warning (0,00 sec)

mysql> CREATE TEMPORARY TABLE TMP_TEST;
ERROR 1113 (42000): A table must have at least 1 column

更新

更新问题后:

mysql> SELECT ts FROM TEST_TABLE;
Field   1:  `ts`
Catalog:    `def`
Database:   `test`
Table:      `TEST_TABLE`
Org_table:  `TEST_TABLE`
Type:       TIMESTAMP
Collation:  binary (63)
Length:     19
Max_length: 19
Decimals:   0
Flags:      NOT_NULL BINARY TIMESTAMP 

+---------------------+
| ts                  |
+---------------------+
| 2016-11-04 00:00:01 |
+---------------------+
1 row in set (0,00 sec)

mysql> SELECT * FROM (SELECT ts FROM TEST_TABLE) wrap;
Field   1:  `ts`
Catalog:    `def`
Database:   `test`
Table:      `wrap`
Org_table:  `*`
Type:       TIMESTAMP
Collation:  utf8_general_ci (33)
Length:     57
Max_length: 19
Decimals:   0
Flags:      NOT_NULL BINARY TIMESTAMP 

+---------------------+
| ts                  |
+---------------------+
| 2016-11-04 00:00:01 |
+---------------------+
1 row in set (0,00 sec)

注意排序规则的区别。

mysql> CREATE TEMPORARY TABLE TMP_TEST
    -> SELECT * FROM (SELECT BINARY ts FROM TEST_TABLE) wrap;
Query OK, 1 row affected (0,00 sec)
Records: 1  Duplicates: 0  Warnings: 0

更新 2

当查询尝试创建临时表时,子查询导致ts列的默认值被定义为'0000-00-00 00:00:00'并且服务器必须在变量SQL_MODE中配置NO_ZERO_DATE值,这会导致错误。

mysql> SELECT FIND_IN_SET('NO_ZERO_DATE', @@SQL_MODE);
+-----------------------------------------+
| FIND_IN_SET('NO_ZERO_DATE', @@SQL_MODE) |
+-----------------------------------------+
|                                       4 |
+-----------------------------------------+
1 row in set (0,00 sec)

SQL_MODE 中删除NO_ZERO_DATE

mysql> SELECT FIND_IN_SET('NO_ZERO_DATE', @@SQL_MODE);
+-----------------------------------------+
| FIND_IN_SET('NO_ZERO_DATE', @@SQL_MODE) |
+-----------------------------------------+
|                                       0 |
+-----------------------------------------+
1 row in set (0,00 sec)

mysql> DROP TEMPORARY TABLE IF EXISTS TMP_TEST;
Query OK, 0 rows affected (0,00 sec)

mysql> CREATE TEMPORARY TABLE TMP_TEST
    -> SELECT * FROM (SELECT ts FROM TEST_TABLE) wrap;
Query OK, 1 row affected (0,00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SHOW CREATE TABLE TMP_TEST\G
*************************** 1. row ***************************
       Table: TMP_TEST
Create Table: CREATE TEMPORARY TABLE `TMP_TEST` (
  `ts` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB
1 row in set (0,00 sec)

您可以通过删除子查询来避免该问题。

mysql> SELECT FIND_IN_SET('NO_ZERO_DATE', @@SQL_MODE);
+-----------------------------------------+
| FIND_IN_SET('NO_ZERO_DATE', @@SQL_MODE) |
+-----------------------------------------+
|                                       4 |
+-----------------------------------------+
1 row in set (0,00 sec)

mysql> DROP TEMPORARY TABLE IF EXISTS TMP_TEST;
Query OK, 0 rows affected (0,00 sec)

mysql> CREATE TEMPORARY TABLE TMP_TEST
    -> SELECT ts FROM TEST_TABLE;
Query OK, 1 row affected (0,00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SHOW CREATE TABLE TMP_TEST\G
*************************** 1. row ***************************
       Table: TMP_TEST
Create Table: CREATE TEMPORARY TABLE `TMP_TEST` (
  `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB
1 row in set (0,00 sec)

【讨论】:

  • 谢谢,但这不是我发布的代码......你正在做的是不同的事情。您得到的错误 (1113) 是预期的,因为您没有向临时表声明任何列。要重现此问题,您需要以相同的顺序执行语句,并将第 4 行和第 5 行一起执行(这是一个语句)
  • 刚刚编辑了我的问题以避免混淆。问题发生在最后一条语句上。
  • @romric:更新答案。
  • 听起来像是有关该问题的线索,但仍不能 100% 确定理解。所以当使用第二个选择时,排序规则会以某种方式改变?这如何干扰定义的时间戳的默认值?顺便说一句,你如何打印这个有用的字段详细信息?
  • @romric:更新了答案,您可以使用5.5.1 mysql - The MySQL Command-Line Tool 中的--column-type-info 选项。
猜你喜欢
  • 2019-06-15
  • 1970-01-01
  • 2018-10-13
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多