【问题标题】:How can I fix MySQL error #1064?如何修复 MySQL 错误 #1064?
【发布时间】:2014-06-24 06:51:18
【问题描述】:

向 MySQL 发出命令时,我收到错误 #1064 "syntax error"。

  1. 什么意思?

  2. 我该如何解决?

【问题讨论】:

    标签: mysql parsing syntax syntax-error mysql-error-1064


    【解决方案1】:

    TL;DR

    错误 #1064 表示 MySQL 无法理解您的命令。修复它:

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

    • 检查您的命令。如果您使用编程语言创建命令,请使用echoconsole.log() 或其等效项来显示整个命令 em> 这样你就可以看到了。

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

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

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

      错误消息可能看起来像 gobbledygook,但它们(通常)提供了令人难以置信的信息,并提供了足够的详细信息来查明问题所在。通过准确了解 MySQL 告诉您的内容,您可以武装自己,在未来解决任何此类问题。

      与许多程序一样,MySQL 错误是根据发生的问题的类型进行编码的。 Error #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 告诉我们,就WHERE 这个词而言,一切似乎都很好,但随后遇到了问题。换句话说,它没想到会在那个时候遇到WHERE

        显示...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);
        

        然后您可以添加echo $query;var_dump($query) 以查看查询实际上说的是

        UPDATE userSET name='foo' WHERE id=101
        

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

      • 服从命令!

        MySQL 还建议我们“查看与我们的 MySQL 版本相对应的手册以获取正确的语法使用”。让我们这样做吧。

        我正在使用 MySQL v5.6,所以我将转向 that version's manual entry for an UPDATE command。页面上的第一件事是命令的语法(对于每个命令都是如此):

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

        该手册解释了如何在Typographical and Syntax Conventions 下解释此语法,但就我们的目的而言,认识到以下内容就足够了:方括号[] 中包含的子句是可选的;竖线| 表示备选方案;和省略号... 表示为简洁起见省略,或者前面的子句可以重复。

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

      预订说明

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

      我说“几乎所有”,因为有一小部分问题不太容易发现——这就是解析器认为遇到的语言元素意味着一件事,而您打算让它意味着另一件事的地方。举个例子:

      UPDATE my_table SET where='foo'
      

      同样,解析器此时不希望遇到WHERE,因此会引发类似的语法错误——但您并没有打算将 where 用作 SQL 关键字:您本来打算让它确定要更新的列!但是,正如Schema Object Names 中所述:

      如果标识符包含特殊字符或者是保留字,您必须在引用它时引用它。 (例外:限定名称中的句点后面的保留字必须是标识符,因此不需要引用。)保留字列在Section 9.3, “Keywords and Reserved Words”

      [ deletia ]

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

      mysql&gt; <strong>SELECT * FROM `select` WHERE `select`.id &gt; 100;</strong>

      如果启用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)

    【讨论】:

    • 似乎只是列键的错误,必须是保留字,我将不回答这个问题 - 因为我还没有解决它,
    • @hreinn1000: KEY 确实是一个保留字——它出现在我的答案链接到的列表中,dev.mysql.com/doc/en/reserved-words.html。这不是错误,该行为是设计使然并且有据可查。你“没有回答”什么?这篇文章已经是一个完整而完整的答案。
    • 肯定有bug。并不是说我不欣赏您的回答(尽管是居高临下的语气),但就我而言,我的代码中有一个额外的括号,但响应说错误位于“L”下方的第 651 行(共 850 行)。
    【解决方案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 ;
    

    【讨论】:

    • 这不是“问题”。您必须在输入 proc 时使用自定义分隔符,因为它使用与常规命令相同的分隔符。
    • 这就是我们所说的问题。我认为您将“问题”的含义与“错误”的含义混淆了,这不是这里的意思。
    • 这里的问题是,并非所有环境都需要自定义分隔符,当脚本在开发环境中正常工作时,在测试或生产环境中无法按预期工作并产生错误时会导致问题。
    【解决方案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 是保留字,所以我必须用 `` 引号包裹组或更改表名来解决这个问题。

    【讨论】:

      猜你喜欢
      • 2014-07-12
      • 2014-12-11
      • 2015-06-08
      • 1970-01-01
      • 2019-11-29
      • 1970-01-01
      • 2011-02-11
      • 2015-07-03
      相关资源
      最近更新 更多