如何修复MySQL错误#1064?

How can I fix MySQL error #1064?

提问人:eggyal 提问时间:5/7/2014 更新时间:7/18/2021 访问量:475152

问:

向MySQL发出命令时,我收到错误#1064“语法错误”。

  1. 这是什么意思?

  2. 我该如何解决?

MySQL 解析 语法 mysql错误-1064

评论


答:

143赞 3 revs, 3 users 91%eggyal #1

TL;博士

错误#1064表示MySQL无法理解您的命令。要修复它,请执行以下操作:

  • 阅读错误消息。它准确地告诉您MySQL在命令中的位置感到困惑。

  • 检查您的命令。如果使用编程语言创建命令,请使用 、 或等效项来显示整个命令,以便您可以查看它。echoconsole.log()

  • 查看手册。通过与MySQL当时的预期进行比较,问题通常是显而易见的。

  • 检查保留字。如果错误发生在对象标识符上,请检查它是否不是保留字(如果是,请确保正确引用)。

  1. 啊啊!!#1064 是什么意思

    错误消息可能看起来像 gobbledygook,但它们(通常)信息量非常大,并提供足够的细节来查明出了什么问题。通过准确理解MySQL告诉你的内容,你可以武装自己,在未来解决任何此类问题。

    与许多程序一样,MySQL错误是根据发生的问题类型进行编码的。错误 #1064 是语法错误。

    • 你说的这个“语法”是什么?是巫术吗?

      虽然“语法”是许多程序员只在计算机环境中遇到的一个词,但它实际上是从更广泛的语言学中借来的。它指的是句子结构:即语法规则;或者,换句话说,定义语言中有效句子构成的规则。

      例如,以下英语句子包含语法错误(因为不定冠词“a”必须始终位于名词之前):

      这句话包含语法错误 a。

    • 这与MySQL有什么关系?

      每当向计算机发出命令时,它必须做的第一件事就是“解析”该命令以理解它。“语法错误”意味着解析器无法理解所询问的内容,因为它不构成语言中的有效命令:换句话说,该命令违反了编程语言的语法

      请务必注意,计算机必须先理解该命令,然后才能对其进行任何操作。由于存在语法错误,MySQL不知道在追求什么,因此在查看数据库之前就放弃了,因此模式或表内容不相关。

  2. 我该如何解决?

    显然,需要确定该命令是如何违反MySQL语法的。这听起来可能很难以理解,但MySQL非常努力地帮助我们。我们需要做的就是......

    • 阅读消息!

      MySQL不仅告诉我们解析器在何处遇到语法错误,而且还提出了修复建议。例如,请考虑以下 SQL 命令:

      UPDATE my_table WHERE id=101 SET name='foo'
      

      该命令将生成以下错误消息:

      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 'WHERE id=101 SET name='foo'' at line 1

      MySQL告诉我们,一切似乎都很好,但随后遇到了一个问题。换句话说,它没想到会在那个时候遇到。WHEREWHERE

      显示的消息仅表示意外遇到命令结束:也就是说,在命令结束之前应该出现其他内容。...near '' at line...

    • 检查命令的实际文本!

      程序员通常使用编程语言创建 SQL 命令。例如,一个 php 程序可能有一个(错误的)行,如下所示:

      $result = $mysqli->query("UPDATE " . $tablename ."SET name='foo' WHERE id=101");
      

      如果你把它写成两行

      $query = "UPDATE " . $tablename ."SET name='foo' WHERE id=101"
      $result = $mysqli->query($query);
      

      然后,您可以添加 or 查看查询实际上显示echo $query;var_dump($query)

      UPDATE userSET name='foo' WHERE id=101
      

      通常,您会立即看到错误并能够修复它。

    • 服从命令!

      MySQL还建议我们“检查与我们的MySQL版本相对应的手册,了解正确的语法”。让我们开始吧。

      我使用的是 MySQL v5.6,因此我将转到该版本的手动条目以获取 UPDATE 命令。页面上的第一件事是命令的语法(每个命令都是如此):

      UPDATE [LOW_PRIORITY] [IGNORE] table_reference
          SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
          [WHERE where_condition]
          [ORDER BY ...]
          [LIMIT row_count]
      

      本手册解释了如何在印刷和语法约定下解释此语法,但就我们的目的而言,认识到以下几点就足够了:包含在方括号内的子句是可选的;竖条表示替代方案;省略号表示为简洁起见而省略,或者可以重复前面的子句。[]|...

      我们已经知道,解析器认为我们命令中的所有内容在关键字之前都是正常的,换句话说,直到并包括表引用。看一下语法,我们看到table_reference后面必须跟着关键词:而在我们的命令中,它后面实际上跟着关键词。这解释了为什么分析器报告当时遇到了问题。WHERESETWHERE

    保留须知

    当然,这只是一个简单的例子。但是,通过遵循上述两个步骤(即观察解析器在命令中发现语法被违反的确切位置,并与手册对当时预期内容的描述进行比较),几乎每个语法错误都可以很容易地识别出来。

    我说“几乎所有”,因为有一小类问题不太容易被发现——这就是解析器认为遇到的语言元素意味着一件事,而你希望它意味着另一件事。以以下示例为例:

    UPDATE my_table SET where='foo'
    

    同样,解析器预计此时不会遇到,因此会引发类似的语法错误——但您并不打算将其作为 SQL 关键字:您打算让它识别要更新的列!但是,如架构对象名称中所述:WHEREwhere

    如果标识符包含特殊字符或为保留字,则在引用它时必须引用它。(例外:限定名称中句点后面的保留字必须是标识符,因此不需要引号。保留字列在第 9.3 节 “关键字和保留字”中。

    [ deletia ]

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

    mysql> SELECT * FROM `select` WHERE `select`.id > 100;

    如果启用了 ANSI_QUOTES SQL 模式,则还允许在双引号内引用标识符:

    mysql> CREATE TABLE "test" (col INT);
    ERROR 1064: You have an error in your SQL syntax...
    mysql> SET sql_mode='ANSI_QUOTES';
    mysql> CREATE TABLE "test" (col INT);
    Query OK, 0 rows affected (0.00 sec)

评论

0赞 hreinn1000 7/11/2018
似乎只针对列键的错误,必须是保留字,我将不回答这个问题 - 因为我还没有解决它,
1赞 eggyal 7/11/2018
@hreinn1000:确实是一个保留词——它出现在我的答案链接到的列表中,dev.mysql.com/doc/en/reserved-words.html。这不是一个错误,该行为是设计使然且有据可查。你“没有回答”什么?这篇文章已经是一个完整而完整的答案。KEY
0赞 David S 9/30/2021
肯定有一个错误。并不是说我不欣赏你的回答(尽管是居高临下的语气),但就我而言,我的代码中有一个额外的括号,但回复说错误在第 651 行(共 850 行)下方的“L”。
1赞 Umair Malhi 4/19/2017 #2

就我而言,我试图在MySQL中执行过程代码,并且由于服务器的一些问题,服务器无法确定在哪里结束语句,我收到错误代码1064。因此,我用自定义DELIMITER包装了该过程,它工作正常。

例如,在它是:

DROP PROCEDURE IF EXISTS getStats;
CREATE PROCEDURE `getStats` (param_id INT, param_offset INT, param_startDate datetime, param_endDate datetime)
BEGIN
    /*Procedure Code Here*/
END;

放置 DELIMITER 后,情况是这样的:

DROP PROCEDURE IF EXISTS getStats;
DELIMITER $$
CREATE PROCEDURE `getStats` (param_id INT, param_offset INT, param_startDate datetime, param_endDate datetime)
BEGIN
    /*Procedure Code Here*/
END;
$$
DELIMITER ;

评论

1赞 ivan_pozdeev 5/14/2019
这不是一个“问题”。输入过程时必须使用自定义分隔符,因为它使用与常规命令相同的分隔符。
0赞 Umair Malhi 5/15/2019
这就是我们所说的问题。我认为您将“问题”的含义与“错误”混淆了,这里并不意味着“错误”。
0赞 Umair Malhi 5/15/2019
这里的问题是,并非所有环境都需要自定义分隔符,当在开发环境中正常工作的脚本在测试或生产环境中无法按预期工作并生成错误时,这会导致问题。
3赞 Muhammad Shahzad 7/18/2021 #3

虽然很晚了,但会帮助别人,当然也会节省时间:) 我的查询在本地系统的 MySQL 5.7 中工作,但在实时,我们有 MySQL 8 版本并且查询停止工作。

查询:

SELECT t.*
FROM groups t
ORDER BY t.id DESC
LIMIT 10 OFFSET 0

MySQL 8 中的输出:

查询中的错误 (1064):“groups t ORDER BY t.id DESC”附近的语法错误 在线...

我开始知道是保留字,所以我必须用“”引号包装组或更改表名来解决此问题。groups