如何修复MySQL错误#1064?

时间:2014-05-07 10:32:32

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

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

  1. 这是什么意思?

  2. 我该如何解决?

3 个答案:

答案 0 :(得分:109)

  

TL; DR

     

错误#1064意味着MySQL无法理解您的命令。解决它:

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

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

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

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

  •   
  1. Aaaagh !! #1064 是什么意思

    错误消息可能看起来像,但他们(经常)提供了非常丰富的信息,并提供足够的细节来查明出错的地方。通过准确理解MySQL告诉你的内容,你可以在将来武装自己解决这类问题。

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

    • 这是什么"语法"你在说什么?这是巫术吗?

      同时"语法"这是许多程序员只在计算机环境中遇到的一个词,它实际上借鉴了更广泛的语言学。它指的是句子结构:即语法规则;或者换句话说,定义在语言中构成有效句子的内容的规则。

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

        

      这句话包含语法错误a。

    • 这与MySQL有什么关系?

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

      重要的是要注意,计算机必须先了解该命令,然后才能对其执行任何操作。因为存在语法错误,所以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关键字:而在我们的命令中,实际上后跟{ {1}}关键字。这解释了解析器报告此时遇到问题的原因。

    预订说明

    当然,这是一个简单的例子。但是,通过遵循上面概述的两个步骤(即,观察命令中的确切位置,解析器发现要违反的语法,并与手册对的预期描述进行比较这一点),几乎每个语法错误都可以轻松识别。

    我说"几乎所有",因为有一小部分问题并不那么容易发现 - 这就是解析器认为语言元素遇到的意思一件事,而你打算意味着另一件事。请看以下示例:

    WHERE

    同样,解析器此时不会遇到UPDATE my_table SET where='foo' 因此会引发类似的语法错误 - 但您并不打算将WHERE作为SQL关键字:您原本打算用它来识别要更新的列!但是,如Schema Object Names所述:

      

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

    [ deletia ]
         

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

    `
         

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

         

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

答案 1 :(得分:0)

对于我的情况,我试图在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 ;

答案 2 :(得分:0)

很晚了,但会帮助别人,当然会节省时间:) 我的查询在本地系统的 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 是保留字,所以我必须用 `` 引号将组括起来或更改表名来解决这个问题。