我如何解决MySQL错误#1064?

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

  1. 这是什么意思?

  2. 我该如何解决?

TL; DR

错误#1064意味着MySQL不能理解你的命令。 要解决这个问题:

  • 阅读错误消息。 它会告诉你到底你的命令在哪里 MySQL弄糊涂了。

  • 检查手册。 通过比较MySQL 在这一点上的预期 ,问题往往是显而易见的。

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

  1. Aaaagh! #1064 什么意思

    错误消息可能看起来象征食物,但它们(通常)是非常丰富的信息,并提供足够的细节来查明哪里出了问题。 通过了解MySQL正在告诉你什么,你可以武装自己来解决这类问题。

    和许多程序一样,MySQL错误是根据发生的问题types编码的。 错误#1064是一个语法错误。

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

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

      例如,以下英语句子包含语法错误(因为不定冠词“a”必须总是在名词前面):

      这句话包含语法错误a。

    • 这与MySQL有什么关系?

      每当向计算机发出命令时,首先要做的事情之一就是“parsing”该命令,以便理解它。 “语法错误”意味着parsing器无法理解所要求的内容,因为它不构成语言中的有效命令:换句话说, 命令违反了编程语言的语法

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

  2. 我该如何解决?

    显然,需要确定命令是如何违反MySQL的语法的。 这听起来相当难以理解,但MySQL正在努力帮助我们。 我们所需要做的就是…

    • 阅读信息!

      MySQL不仅告诉我们parsing器在哪里遇到了语法错误,而且还提出了解决这个问题的build议。 例如,考虑下面的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

      那些在...near '' at line......near '' at line...消息只是意味着遇到意外的命令结束:也就是说,在命令结束之前应该出现其他的东西。

    • 服从命令!

      MySQL还build议我们“ 检查与我们的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 ] 

      本手册解释了如何在印刷和语法约定下解释这个语法,但是为了我们的目的,足以认识到:方括号[]中包含的子句是可选的; 垂直条| 指出替代品; 和省略号表示为简洁省略,或者可以重复前面的条款。

      我们已经知道parsing器相信我们的命令中的所有内容在WHERE关键字之前是可以的,或者换句话说直到并包括表引用。 查看语法,我们看到table_reference必须跟随SET关键字:而在我们的命令中,其实后面跟着WHERE关键字。 这就解释了为什么parsing器报告在这一点上遇到了问题。

    留意一下

    当然,这是一个简单的例子。 然而,通过遵循上面概述的两个步骤(即, 准确地观察语法分析器在哪里发现语法被违反,并且与手册对该点期望内容的描述进行比较),实际上每个语法错误都可以容易地识别。

    我说“几乎所有的”,因为有一小部分问题不太容易发现 – parsing器认为遇到的语言元素意味着一件事,而你打算意味着另一件事。 以下面的例子:

     UPDATE my_table SET where='foo' 

    此外,parsing器不会期望在这一点上遇到WHERE ,所以会引发类似的语法错误 – 但是您并没有打算将它作为一个SQL关键字:您打算让它识别一个更新的列! 但是,如在“ 架构对象名称”下logging的那样:

    如果标识符包含特殊字符或是保留字,则只要引用标识符就必须引用该标识符。 (例外:在限定名称后面的句点必须是标识符,因此不需要引用。)保留字在第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) 

如果您在使用像CREATE PROCEDURE这样的分号运行SQLexpression式时收到SQuirreL Client的错误,那么您需要MySQL插件。 您可以在安装时select它。 它没有被默认选中。

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

当您尝试插入带有特殊字符的JSON或其他数据时,也会出现此错误,而不需要引号,例如:

 UPDATE myTable SET myJSONfield = {}; 

改变它

 UPDATE myTable SET myJSONfield = '{}'; 

它的各种原因..说如果我们声明任何variables,那么它应该在任何其他types的语句之前。 否则我们需要在此之前放置一个BEGIN块。

 DECLARE _RoomID INTEGER ; SET _dtTodayTmp=NOW(); SET _dtToday=DATE_FORMAT(_dtTodayTmp,"%m/%d/%y"); SET _tmNow=DATE_FORMAT(_dtTodayTmp,"%h:%i:%s"); DECLARE tree_cursor1 CURSOR FOR SELECT roomid FROM reservationDet rd WHERE rd.status=3 AND rd.compcode=pCompCode; 

给出错误,所以我们需要做到这一点

 DECLARE _RoomID INTEGER ; SET _dtTodayTmp=NOW(); SET _dtToday=DATE_FORMAT(_dtTodayTmp,"%m/%d/%y"); SET _tmNow=DATE_FORMAT(_dtTodayTmp,"%h:%i:%s"); **BEGIN** DECLARE tree_cursor1 CURSOR FOR SELECT roomid FROM reservationDet WHERE STATUS = 3 AND compcode = pCompCode ;