向MySQL发出命令时,我收到错误#1064"语法错误"。
这是什么意思?
我该如何解决?
答案 0 :(得分:109)
TL; DR
错误#1064意味着MySQL无法理解您的命令。解决它:
阅读错误消息。它告诉您命令中的确切位置 MySQL感到困惑。
检查您的命令。如果您使用编程语言创建命令,请使用
echo
,console.log()
或其等效语言来显示整个命令所以你可以看到它。查看手册。通过比较MySQL 当时的预期,问题通常很明显。
检查保留字。如果对象标识符发生错误,请检查它是否为保留字(如果是,请确保它是'正确引用。)
错误消息可能看起来像
与许多程序一样,MySQL错误根据发生的问题的类型进行编码。 Error #1064是语法错误。
同时"语法"这是许多程序员只在计算机环境中遇到的一个词,它实际上借鉴了更广泛的语言学。它指的是句子结构:即语法规则;或者换句话说,定义在语言中构成有效句子的内容的规则。
例如,以下英语句子包含语法错误(因为不定冠词" a"必须始终位于名词之前):
这句话包含语法错误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
关键字:而在我们的命令中,实际上后跟{ {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
是保留字,所以我必须用 `` 引号将组括起来或更改表名来解决这个问题。