|
|
子查询里的列名匹配
子查询里的列名匹配
--王成辉翻译整理,转帖请注明出自微软BI开拓者www.windbi.com --原帖地址 子查询里的列匹配有点特殊。如果你曾经遇到过的话,那么可能不会犯第二次错了。现在让我们花点时间来研究一下。 有个表叫users,为了简便,只列出一部分必须的列: CREATE TABLE dbo.Users ( UserID INT PRIMARY KEY, -- ... other columns ... ); 针对这个表,要选出特定的一些用户出来,具体的代码简单如下: DECLARE @u TABLE (id INT PRIMARY KEY); INSERT @u(id) SELECT 1 UNION ALL SELECT 2; SELECT UserID FROM dbo.Users WHERE UserID IN (SELECT UserID FROM @u); 请注意子查询里的列是userid,而不是id。运行这个查询,居然得到了源表的全部用户。为什么啊?大部分情况下不会有任何影响,但在子查询里,如果在引用的对象上找到不列,编译器就会试着在父查询里来绑定那列。如果没有找到的话,就会得到一个错误(非法的列名);如果找到了多个的话,会得到另一个错误(列名不明确)。但当正好有一个的时候,上面的查询就可以重写成下面的语句: SELECT UserID FROM dbo.Users WHERE UserID IN (SELECT UserID FROM dbo.Users); -- which of course becomes: SELECT UserID FROM dbo.Users; 注意如果@u没有记录的话,外层的查询也会没有记录返回。但如果只要子查询里有一条记录,那么外层查询就会返回所有的记录。这种错误很难诊断,所以一定要小心。 |
|
|