Sql 查询不存在的列不会失败

Sql 查询不存在的列不会失败,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,奇怪的情况 如果我有这些表格: CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT) GO CREATE TABLE t2 (id INT, t1Id INT, someData VARCHAR(20)) GO 并且做: SELECT t1.* FROM t1 WHERE t1.id IN (SELECT someIntCol FROM t2) 奇怪的是:解析器并不介意someIntCol列不存在 最奇怪

奇怪的情况

如果我有这些表格:

CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT)
GO
CREATE TABLE t2 (id INT, t1Id INT, someData VARCHAR(20))
GO
并且做:

SELECT    t1.* 
FROM    t1 
WHERE    t1.id IN (SELECT someIntCol FROM t2)
奇怪的是:解析器并不介意someIntCol列不存在

最奇怪的是:如果我将someIntCol更改为someIntCol2,就会得到一个无效的列名“someIntCol2”。错误

有人能解释一下吗

仅供参考,这不是我的代码。我是从link下载的,试试看:

SELECT    t1.* 
FROM    t1 
WHERE    t1.id IN (SELECT t2.someIntCol FROM t2)
这将在执行时引发异常

因为someIntCol存在于t1中,所以它正在使用来自主查询的数据项

子查询可以使用主查询中的数据项。因此,为避免出现这种情况,请在输入数据项时指定表名:

SELECT [TableName].[ColumnName]
如果在t1和t2中有两列名称相同,这也可以防止歧义

以下是MSDN,它可以让您更好地了解子查询的工作原理:


解析器不介意,因为他看到t1中的someIntCol列。您没有指定他应该从哪个表中获取某些Intcol,所以解析器假定您想要从t1获取它。

您能找到吗

SELECT    t1.*  FROM    t1  WHERE    t1.id IN (SELECT someIntCol FROM t2)
表T2没有someIntCol列


因此,解析器在SQL Server中显示错误

。解析步骤仅从语义上检查语法,如以数字开头的未scaped列,如[2ndColumn]和不会解析失败的2ndColumn,关键字等,并确保可以解析查询。这是在SSMS中单击parse按钮时发生的过程。此过程不会针对基础数据验证查询

因此,我可以从DEF中键入selectabc,即使我没有任何名为abc的列,甚至没有名为DEF的表格

下一步是algebrizer,这是绑定的过程。这一步在解析查询时不会发生,它确保查询的每个对象都实际存在,并且在引用不存在的对象时会失败

验证这一点的另一种方法是告诉SQL Server仅解析,而不执行任何其他操作:

SET PARSEONLY ON
SELECT abc FROM def
GO
上面的查询将显示命令已成功执行

SET PARSEONLY OFF
SELECT abc FROM def
GO
上述查询将显示无效的对象名称“def”


在示例问题中,someIntCol列存在于查询的范围内,因为您尚未从中指定特定的原点。resultwise,这没有多大意义,但它仍然不是一个无效的查询。

+1:始终指定表名,否则您可能会引用另一个表中的列,可能是来自更大范围的列。不是真的。此查询也将进行精细解析,因为它是可解析的。不管解析步骤中是否存在内容。@cairnz我已经编辑了我的答案以指定执行。我相信它在执行时会抛出异常,但在解析时不会。我理解解释,但我不明白如何从t2中选择t1中的列。@Diego-这是因为t2在t1的子查询中,子查询可以访问主查询项。我给了您投票,因为这是一个非常好的知识。我也可能误用了parse这个词。我的观点是,即使列不存在,也会运行查询。但是现在我看到我在表1上做了。无论如何谢谢你