【发布时间】:2014-06-24 06:51:18
【问题描述】:
向 MySQL 发出命令时,我收到错误 #1064 "syntax error"。
什么意思?
我该如何解决?
【问题讨论】:
标签: mysql parsing syntax syntax-error mysql-error-1064
向 MySQL 发出命令时,我收到错误 #1064 "syntax error"。
什么意思?
我该如何解决?
【问题讨论】:
标签: mysql parsing syntax syntax-error mysql-error-1064
TL;DR
错误 #1064 表示 MySQL 无法理解您的命令。修复它:
阅读错误消息。它告诉您您的命令的确切位置MySQL 感到困惑。
检查您的命令。如果您使用编程语言创建命令,请使用
echo、console.log()或其等效项来显示整个命令 em> 这样你就可以看到了。查看手册。通过与 MySQL当时的预期进行比较,问题通常很明显。
检查保留字。如果错误发生在对象标识符上,请检查它是否不是保留字(如果是,请确保正确引用它)。
错误消息可能看起来像 gobbledygook,但它们(通常)提供了令人难以置信的信息,并提供了足够的详细信息来查明问题所在。通过准确了解 MySQL 告诉您的内容,您可以武装自己,在未来解决任何此类问题。
与许多程序一样,MySQL 错误是根据发生的问题的类型进行编码的。 Error #1064 是语法错误。
虽然“语法”是许多程序员只在计算机环境中遇到的一个词,但它实际上是从更广泛的语言学中借来的。它指的是句子结构:即语法规则;或者,换句话说,定义在语言中构成有效句子的规则。
例如,以下英文句子包含语法错误(因为不定冠词“a”必须始终在名词之前):
这句话包含语法错误a。
每当向计算机发出命令时,它必须做的第一件事就是“解析”该命令以便理解它。 “语法错误”意味着解析器无法理解所询问的内容,因为它不构成该语言中的有效命令:换句话说,该命令违反了编程语言的语法。
请务必注意,计算机必须先了解该命令,然后才能对其执行任何操作。由于存在语法错误,MySQL 不知道后面是什么,因此在查看数据库之前就放弃了,因此架构或表内容不相关。
显然,需要确定该命令是如何违反 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> <strong>SELECT * FROM `select` WHERE `select`.id > 100;</strong>如果启用
ANSI_QUOTESSQL模式,也允许在双引号内引用标识符: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)
【讨论】:
KEY 确实是一个保留字——它出现在我的答案链接到的列表中,dev.mysql.com/doc/en/reserved-words.html。这不是错误,该行为是设计使然并且有据可查。你“没有回答”什么?这篇文章已经是一个完整而完整的答案。
就我而言,我试图在 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 ;
【讨论】:
虽然晚了,但会帮助别人,当然会节省时间:) 我的查询在本地系统中的 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 是保留字,所以我必须用 `` 引号包裹组或更改表名来解决这个问题。
【讨论】: