使用无效列名称的表变量的TSQL问题

时间:2017-06-16 15:25:16

标签: sql-server sql-server-2014

问题是引用不在存储过程中的表变量内的列名。我认为这应该产生一个错误,但它会返回值,而不是在主查询中找到列名。

这是一个已知问题,可能在SQL 2016中修复了吗?或者预期这种行为?

DECLARE @LookupTable TABLE(MyId Integer, PRIMARY KEY(MyId));
INSERT INTO @LookupTable (MyId) Values (1);


DECLARE @DataTable TABLE(My_Id Integer, MyOtherField Char(1), PRIMARY KEY(My_Id));
INSERT INTO @DataTable (My_Id,MyOtherField) Values (1,'A');
INSERT INTO @DataTable (My_Id,MyOtherField) Values (2,'B');
INSERT INTO @DataTable (My_Id,MyOtherField) Values (3,'C');


--SELECT MyId works as expected (one row)
SELECT MyOtherField FROM @DataTable
WHERE My_Id IN (SELECT MyId FROM @LookupTable)

--SELECT My_Id should be an error
--Returns three rows when referencing a column name not in @LookupTable
SELECT MyOtherField FROM @DataTable
WHERE My_Id IN (SELECT My_Id FROM @LookupTable)

--Returns expected error: invalid column name 'My_Id'
SELECT My_Id FROM @LookupTable

SQL Server 2014(SP2)。

2 个答案:

答案 0 :(得分:2)

子查询中的

M_Id列是从外表@DataTable引用的。它被称为相关子查询。外表中的列可以在子查询中引用。

现在它会更有意义。

SELECT MyOtherField FROM @DataTable T
WHERE T.My_Id IN (SELECT T.My_Id FROM @LookupTable)

大多数情况下,使用exists时会使用相关的子查询。您可以在Where子句中看到外表中的列将被引用

答案 1 :(得分:1)

[1]关于报告“问题”的更多细节:当前问题考虑以下查询

SELECT MyOtherField FROM @TableA
WHERE ColumnFromTableA IN (SELECT ColumnFromTableA FROM @TableB)

返回意外结果。

[2]这不是一个错误。

[3]这是预期的行为:DBMS(例如SQL Server)在ColumnFromTableA的本地范围内找不到@TableB它将成功执行(没有警告/异常)如果此列存在于@TableA