由于在MySQL中使用保留字作为表名或列名而导致的语法错误

Syntax error due to using a reserved word as a table or column name in MySQL

提问人: 提问时间:5/3/2014 最后编辑:12 revs, 5 users 50%Amal Murali 更新时间:2/8/2021 访问量:221521

问:

这个问题的答案是社区的努力。编辑现有答案以改进此帖子。它目前不接受新的答案或交互。

我正在尝试执行一个简单的MySQL查询,如下所示:

INSERT INTO user_details (username, location, key)
VALUES ('Tim', 'Florida', 42)

但是我收到以下错误:

错误 1064 (42000):SQL 语法中有错误;查看与您的MySQL服务器版本相对应的手册,了解在第1行附近使用的正确语法'key) VALUES ('Tim', 'Florida', 42)'

如何解决此问题?

mysql 保留字

评论

13赞 Álvaro González 5/6/2014
如果您已被重定向到此处,但没有收到任何错误消息,则可能是没有进行错误检查。请为您的语言、库和/或工具寻找有关如何执行此操作的建议——不要在每次出现问题时都在这里发帖。谢谢!
1赞 Abhitalks 5/7/2014
为什么只有 ?这不是跨技术/语言的问题吗?这样的参考/规范问题/答案不应该不适用,而不管标签如何吗?我们是否会单独提供另一个类似的参考 QA,因为反引号不适用于那里;或者或者或者,我们最终可能会得到一百个这样的参考 QA?MySQLSQLServerCC#VB
4赞 BoltClock 5/14/2014
@abhitalks:因为每个实现都有不同的SQL风格,适用于MySQL的内容不一定适用于其他风格。如果各自的社区认为有必要,可能会出现一个参考问题,否则我不会担心它。拥有十几个参考问题胜过拥有数千个重复问题 IMO。
0赞 Flexo 12/3/2014
我在这里应用了 wiki 锁定,因为它开始积累很多没有添加任何东西的答案。

答:

378赞 17 revs, 9 users 54%Amal Murali #1

问题

在MySQL中,某些单词(如,等)是保留字。由于它们具有特殊的含义,因此每当您将它们用作表名、列名或其他类型的标识符时,MySQL 都会将其视为语法错误 - 除非您用反引号将标识符括起来。SELECTINSERTDELETE

正如官方文档中所指出的,在第 10.2 节 架构对象名称(强调后加):

MySQL中的某些对象,包括数据库、表、索引、列、别名、视图、存储过程、分区、表空间和其他对象名称,称为标识符

...

如果标识符包含特殊字符或为保留字,则在引用它时必须引用它。

...

标识符引号字符是反引号 (“”):`

可以在第 10.3 节 关键字和保留字中找到关键字和保留字的完整列表。在该页面中,后跟“(R)”的单词是保留字。下面列出了一些保留字,包括许多容易导致此问题的保留字。

  • 以前
  • 条件
  • 删除
  • DESC
  • 描述
  • 指数
  • 插入
  • 间隔
  • 钥匙
  • 喜欢
  • 限制
  • 火柴
  • 选择
  • 次序
  • 分区
  • 引用
  • 选择
  • 桌子
  • 更新
  • 哪里

解决方案

您有两种选择。

1. 不要使用保留字作为标识符

最简单的解决方案是避免使用保留字作为标识符。您可以为您的列找到另一个不是保留字的合理名称。

这样做有几个优点:

  • 它消除了您或使用数据库的其他开发人员由于忘记或不知道特定标识符是保留字而意外编写语法错误的可能性。MySQL中有许多保留字,大多数开发人员不太可能知道所有这些保留字。首先不使用这些词,可以避免为自己或未来的开发人员留下陷阱。

  • 引用标识符的方法因 SQL 方言而异。虽然MySQL默认使用反引号来引用标识符,但符合ANSI标准的SQL(以及ANSI SQL模式下的MySQL,如此处所述)使用双引号来引用标识符。因此,用反引号引用标识符的查询不太容易移植到其他 SQL 方言。

纯粹为了降低未来出错的风险,这通常是比反引号引用标识符更明智的做法。

2.使用反引号

如果无法重命名表或列,请将有问题的标识符括在反引号 () 中,如前面引用的 10.2 架构对象名称中所述。`

演示用法的示例(摘自 10.3 关键字和保留字):

mysql> CREATE TABLE interval (begin INT, end INT);
ERROR 1064 (42000): You have an error in your SQL syntax.
near 'interval (begin INT, end INT)'

mysql> CREATE TABLE `interval` (begin INT, end INT); Query OK, 0 rows affected (0.01 sec)

同样,可以通过将关键字括在反引号中来修复问题的查询,如下所示:key

INSERT INTO user_details (username, location, `key`)
VALUES ('Tim', 'Florida', 42)";               ^   ^

评论

26赞 Marc Alff 5/7/2014
-1.我认为建议在这个问题的参考答案中使用不带反引号的开始和结束是特别邪恶的。更好的做法是使用反引号、句点,而不必知道哪个关键字是保留的或非保留的。
18赞 Amal Murali 5/7/2014
@MarcAlff:并且不是保留字。上面的示例只是为了演示如何使用反引号解决错误消息。而且,简单地不使用保留字比盲目地反引号引用所有标识符(即使不需要它们)要好。beginend
4赞 Marc Alff 5/7/2014
我同意解决方案 1 更好,当有人可以实际选择标识符名称时。当名称无法更改时,如解决方案 2 中所示,必须调查哪些标识符是关键字,以及这些关键字是否保留(即使将来的版本?),是复杂性的根源。顺便说一句,删除了 -1,因为示例实际上来自手册。
18赞 Marc Alff 5/7/2014
在MySQL中经常创建新的保留字,并发布新版本。例如,MySQL 5.7 中的 NONBLOCKING。系统地报价往往对变化更稳健,并有助于升级。至于删除 -1,我很乐观。你是对的,由于这个计时器,我的删除失败了。
5赞 Dour High Arch 11/19/2018
使用保留字作为标识符的另一个缺点是:它使搜索代码变得不可能。如果命名其中一个表,则搜索它将返回过多的误报。Table