我如何解决MySQL错误#1064?
向MySQL发出命令时,出现错误#1064“语法错误”。
-
这是什么意思?
-
我该如何解决?
TL; DR
错误#1064意味着MySQL不能理解你的命令。 要解决这个问题:
阅读错误消息。 它会告诉你到底你的命令在哪里 MySQL弄糊涂了。
检查手册。 通过比较MySQL 在这一点上的预期 ,问题往往是显而易见的。
检查保留字。 如果错误发生在对象标识符上,请检查它是否不是保留字(如果是,请确保正确引用它)。
-
Aaaagh! #1064 是什么意思 ?
错误消息可能看起来象征食物,但它们(通常)是非常丰富的信息,并提供足够的细节来查明哪里出了问题。 通过了解MySQL正在告诉你什么,你可以武装自己来解决这类问题。
和许多程序一样,MySQL错误是根据发生的问题types编码的。 错误#1064是一个语法错误。
-
你说这个“语法”是什么? 它是巫术吗?
虽然“语法”是许多程序员只能在计算机环境中遇到的一个词,但实际上它是从更广泛的语言学中借用的。 它指的是句子结构:即语法规则 ; 换句话说,就是规定在语言中构成有效句子的规则。
例如,以下英语句子包含语法错误(因为不定冠词“a”必须总是在名词前面):
这句话包含语法错误a。
-
这与MySQL有什么关系?
每当向计算机发出命令时,首先要做的事情之一就是“parsing”该命令,以便理解它。 “语法错误”意味着parsing器无法理解所要求的内容,因为它不构成语言中的有效命令:换句话说, 命令违反了编程语言的语法 。
请注意,计算机必须先理解命令,然后才能对其执行任何操作。 由于存在语法错误,因此MySQL不知道后面的内容,因此甚至在查看数据库之前放弃,因此模式或表内容不相关。
-
-
我该如何解决?
显然,需要确定命令是如何违反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 ;