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

Ama*_*ali 48 mysql reserved-words

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

INSERT INTO user_details (username, location, key)
VALUES ('Tim', 'Florida', 42)
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

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

我该如何解决这个问题?

Ama*_*ali 265

问题

在MySQL,像某些词SELECT,INSERT,DELETE等等是保留字.由于它们具有特殊含义,因此只要将它们用作表名,列名或其他类型的标识符,MySQL就会将其视为语法错误 - 除非您使用反引号包围标识符.

正如官方文档中所述,在10.2模式对象名称中(重点补充):

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

...

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

...

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

有关关键字和保留字的完整列表,请参见10.3关键字和保留字.在该页面中,后跟"(R)"的单词是保留字.下面列出了一些保留字,包括许多会导致此问题的保留字.

  • 之前
  • 通过
  • 呼叫
  • 案件
  • 条件
  • 删除
  • DESC
  • 描述
  • 指数
  • 插入
  • 间隔
  • IS
  • 喜欢
  • 限制
  • 比赛
  • 选项
  • 要么
  • 订购
  • 划分
  • 参考
  • 选择
  • UPDATE
  • 哪里

解决方案

你有两个选择.

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

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

这样做有几个好处:

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

  • 引用标识符的方法在SQL方言之间有所不同.虽然MySQL使用反引号在默认情况下,符合ANSI标准SQL引用标识符(实际上在MySQL ANSI SQL模式,如注意这里)用来引用标识符双引号.因此,使用反引号引用标识符的查询不太容易移植到其他SQL方言.

纯粹为了降低未来错误的风险,这通常比反引号引用标识符更明智.

2.使用反引号

如果无法重命名表或列,请`按照10.2模式对象名称的前面引用中的描述将有问题的标识符包装在backticks()中.

演示用法的示例(取自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)
Run Code Online (Sandbox Code Playgroud)

类似地,可以通过将关键字包装key在反引号中来修复问题中的查询,如下所示:

INSERT INTO user_details (username, location, `key`)
VALUES ('Tim', 'Florida', 42)";               ^   ^
Run Code Online (Sandbox Code Playgroud)

  • -1.我认为建议在这个问题的参考答案中使用开头和结尾没有反引号是特别邪恶的.更好的做法是使用反引号,句点,而不必知道保留或保留哪个关键字. (21认同)
  • @MarcAlff:`begin`和`end`是*不是*保留字.上面的示例只是为了演示如何使用反引号来解决错误消息.并且简单地不使用保留字是一种更好的做法,而不是盲目地反复引用所有标识符,即使它们不需要也是如此. (14认同)
  • 使用新版本在MySQL中经常创建新的保留字.例如,MySQL 5.7中的NONBLOCKING.系统地引用变更趋于稳健,并有助于升级.至于删除-1,我很乐观.你是对的,我的删除由于这个计时器而失败了. (14认同)
  • 我同意解决方案1更好,当有人可以实际选择标识符名称.当名称无法更改时,如解决方案2中那样,必须调查哪些标识符是关键字,以及这些关键字是否保留(即使未来的版本?),是一个复杂的来源.顺便说一句,删除了-1,因为实例来自手册. (3认同)
  • 使用保留字作为标识符的另一个缺点:使得无法搜索代码。如果您将一个表命名为“表”,那么对其进行搜索将返回过多的误报。 (2认同)