背景
我试图在hackthissite.org中解决fourth realistic mission,并且无法弄清楚我应该在URL中注入哪些SQL来检索电子邮件列表。在浪费了几个小时之后,我放弃了并查看了a solution,它提供了这段有趣的代码,这些代码将在选择查询之后注入:
UNION ALL SELECT NULL, *, NULL, NULL FROM email
我明白这是做什么的,为什么;黑客需要创建一个与其合并的查询具有相同列数的查询,并在*周围移动以确保显示电子邮件。那不是我的问题。
问题
我的问题是为什么代码会在MySQL中引发语法错误。在做了一些测试之后,我发现显然这是一个有效的查询:
SELECT *, NULL, NULL, NULL FROM email
就这样,
SELECT NULL, text, NULL, NULL FROM email
但出于某种原因,这不是:
SELECT NULL, *, NULL, NULL FROM email
并抛出语法错误“near'*,NULL,NULL FROM email'”。 我不明白为什么会这样。看起来这个查询只有在*是请求的第一列时才有效,无论其他列是什么。这是一个错误吗?它是MySQL独有的功能(并且任务使用不同的SQL变体)?还是我完全误解了这个?
答案 0 :(得分:4)
这是documented行为:
使用不合格的*与选择列表中的其他项目可能 产生一个解析错误。要避免此问题,请使用合格的 tbl_name。*参考
按照说明操作。这应该干净地解析:
select NULL, email.*, NULL, NULL from email
答案 1 :(得分:1)
根据数据库的不同,当只使用一个表并选择除了该单个表上的所有列之外的文字时,您必须严格限定表的次数。
例如在Oracle中,即使这是无效的:(反之亦然)
SELECT *, null from email
然而在Postgresql中,是的,它是有效的(两种方式) http://sqlfiddle.com/#!15/20335/2/0
当您使用2+个具有1+同名列的表时,通常会使用限定列来避免歧义错误。歧义错误是普遍存在的。
然而,就解析而言,数据库之间存在差异。 (当您只使用一个表,并从该表中选择所有列,但另外还有文字)