当前位置: 首页 > 知识库问答 >
问题:

MySQL 8:更改表...更改列...使用表达式设置默认值会导致语法错误

徐涵亮
2023-03-14

Mysql 8.0.25

我想使用alter column子句为我的datetime列设置默认值

Mysql 8文档说,在设置默认值之后,出现文本表达式https://dev.mysql.com/doc/refman/8.0/en/alter-table.html

...
| ALTER [COLUMN] col_name {
        SET DEFAULT {literal | (expr)}
      | SET {VISIBLE | INVISIBLE}
      | DROP DEFAULT
    }

所以我做了下面的事情,但没有一件是成功的。

alter table my_table alter column my_datetime_column set default CURRENT_TIMESTAMP();
alter table my_table alter column my_datetime_column set default NOW();
alter table my_table alter column my_datetime_column set default CURRENT_TIMESTAMP;
alter table my_table alter column my_datetime_column set default NOW;

我知道我可以通过改变列来设置默认值。但是为什么不使用改变列呢?我留档有什么问题吗?


共有1个答案

祁烈
2023-03-14

这似乎是MySQL解析器中的一个奇怪差距。

多年来,MySQL列默认值必须是文字标量值,否则为NULL。不支持表达式

MySQL 8.0还支持使用表达式作为默认值的选项,但必须使用括号中的表达式作为语法。

CREATE TABLE MyTable (
  a INT,
  b INT,
  c INT DEFAULT a+b,  -- ERROR
  d INT DEFAULT (a+b) -- CORRECT
);

MySQL timestamp/datetime列有一种特殊的语法,从早期版本开始就受到支持,它允许关键字CURRENT_timestamp而不是文字值。不需要括号。看见https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html

但这似乎不受ALTER TABLE... ALTER COLUMN语句的支持:

alter table mytable alter column dt set default current_timestamp;

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to use
near 'current_timestamp' at line 1

但是,如果您使用MySQL 8.0,如果您遵循较新的表达式默认语法,则可以使用CURRENT_TIMESTAMP,并将其放在括号中:

alter table mytable alter column dt set default (current_timestamp);

Query OK, 0 rows affected (0.01 sec)

您也可以使用不带括号的传统语法,但不能使用ALTER COLUMN。您必须使用MODIFY COLUMN的语法,这要求您指定列的数据类型和可空性。

alter table mytable modify column dt datetime not null default current_timestamp;

Query OK, 0 rows affected (0.01 sec)

这只是SQL解析器中的一个奇怪的不一致性。默认情况下,CURRENT_TIMESTAMP的特殊支持没有扩展到ALTER列子句。据报道,这是一个错误,但被拒绝:https://bugs.mysql.com/bug.php?id=31452

 类似资料:
  • 问题内容: 我有一个表,其中的列类型为默认值,每次更新都更新为。 我想删除此列上的“更新时”功能。如何编写alter语句? 我尝试了以下方法: 但这没用。 问题答案: 皮特几乎是正确的,但对“更改”使用了错误的语法: 请注意,您必须重复列名。另外,请确保您使用反引号而不是单引号来转义列名时间,以防止将其解释为mysql列时间类型。 通过指定CURRENT_TIMESTAMP的默认值,MySQL将不

  • 问题内容: 尝试更改列的数据类型并设置新的默认值时遇到以下错误: 错误1064(42000):您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册,以在第1行的’VARCHAR(255)NOT NULL SET DEFAULT’{}’‘附近使用正确的语法 问题答案: 同样的第二种可能性(感谢juergen_d):

  • 在尝试更改列的数据类型并设置新的默认值时,我遇到以下错误: 错误1064(42000):您的SQL语法中有错误;查看与您的MySQL server版本相对应的手册,以了解第1行“varchar(255)NOT NULL SET DEFAULT”{}“附近使用的正确语法

  • 这就是我得到的错误 我使用的是MySQL5.7版

  • 问题内容: 我有一个需要修改数据库表中列默认值的要求。该表已经是数据库中的现有表,并且当前该列的默认值为NULL。现在,如果将新的默认值添加到此列,如果我是正确的话,它将列的所有现有NULL更新为新的DEfault值。有没有一种方法可以不执行此操作,但仍在列上设置新的默认值。我的意思是我不想更新现有的NULL,并希望它们保留为NULL。 在这方面的任何帮助,不胜感激。谢谢 问题答案: 您对将会发生

  • 它实际做的是创建另一个列表,遍历旧列表,并将元素始终添加到新列表的head。 但是,当我决定重新实现这个想法而不查看这段代码时,我更改了的位置,并将其放在之后 我的问题是这真的有什么不同吗?我无法理解其中的原因,因为毕竟您在遍历旧列表。为什么要求在*temp声明后立即执行?