MySQL:"在关键字附近出现 SQL 语法错误..."?

4
我发现了一个非常酷的丢失密码脚本,但是这一行让我有些困惑。
$r = mysql_query('INSERT INTO `keys` (username,key, vreme) VALUES ("'.$user.'", "'.$acckey.'", "'.$keyexp.'"') or die(mysql_error());

错误

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 'key, vreme) VALUES ("123123", "1ed2f5100a26298a55b2935cbea7d4a0", "1337991670"' at line 1

我会说“构建包含值的SQL字符串”。请参阅Little Bobby Tables的尾部。(抛开这一切,尝试在CLI中查询,因为这种问题——保留字——很容易找到。我已经提炼了错误信息并将其放在标题中供您参考。) - user166390
@pst:你无法确定 $user 和其他变量在之前是如何处理的。在每个主题中都阅读可能的 SQL 注入问题变得很烦人(尤其是在那些很可能没有任何问题的主题中)。 - zerkms
@zerkms 对我来说无所谓/我不在乎:手动字符串构建->太麻烦了,而且很容易出错。 简单的一致性和可重复性可以使代码整洁。 - user166390
@pst:但是你知道 - 你在这里提到Bobby-Tables 完全 不相关。问题是关于语法错误,而不是最佳实践。他不知道基本的东西,你却开始谈论火箭科学。 - zerkms
@pst:谈论 bobby tables 在这里确实是无关的。你只有在代码中明显存在漏洞时才应该提到它。你不能说那个查询容易受攻击。 - itachi
@itachi 我只能希望有人在某个地方阅读了那个链接,世界因此变得更好的编码。甚至这篇文章的作者也可能会受益。 - user166390
6个回答

10

KEY 是一个保留字。根据模式对象名称文档所述:

如果标识符包含特殊字符或是保留字,您在引用它时必须对其加引号。(例外情况:在限定名中跟在句点后面的保留字必须是标识符,因此不必加引号。)

[ deletia ]

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

mysql> <strong>SELECT * FROM `select` WHERE `select`.id > 100;</strong>
如果启用了ANSI_QUOTES SQL模式,则也可以使用双引号引用标识符:

mysql> <strong>CREATE TABLE "test" (col INT);</strong>
ERROR 1064: You have an error in your SQL syntax...
mysql> <strong>SET sql_mode='ANSI_QUOTES';</strong>
mysql> <strong>CREATE TABLE "test" (col INT);</strong>
Query OK, 0 rows affected (0.00 sec)

Therefore:

mysql_query("INSERT INTO `keys` (username, `key`, vreme) VALUES ('$user', '$acckey', '$keyexp') ")

5

key 是一个保留字 - 请用反引号将其括起来。

`key`

2
 $r = mysql_query("INSERT INTO `keys` (username,`key`,vreme) VALUES ('$user', '$acckey','$keyexp')") or die(mysql_error());

谢谢大家(:

1

同时在查询中删除双引号,并用双引号而不是单引号封装查询。

在查询中使用单引号来封装值。


1
你的查询在最后一个闭括号和分号之间缺少单引号吗?

我认为单引号实际上在倒数第二个闭括号之前,这是正确的,因为这是查询结束的地方。 - Jeremy Goodell

1
$r = mysql_query("INSERT INTO `keys` (username,key,vreme) VALUES ('".$user."', '".$acckey."','".$keyexp."')") or die(mysql_error());

还是一样,我现在要去睡觉了,明天再试一次。 - Благовест Тодоров
@Благовест Тодоров:再试一次 什么?我一个小时前已经给出了答案。 - zerkms
那么zerkms是正确的。@zerkms我以为你的答案意味着在保留关键字周围加上反引号。虽然我从未将保留关键字用于表名,但查询本身也很糟糕,所以我已经修复了它。 - Ronnie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接