【问题标题】:TSQL Issue with Table Variable using invalid column names使用无效列名的表变量的 TSQL 问题
【发布时间】:2017-06-16 15:25:15
【问题描述】:

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

这是一个已知问题,或许已在 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)。

【问题讨论】:

  • 我以前见过这种行为,从这个意义上说它是预期的......如果你正确识别列(即:from @DataTable DT where DT.My_id 等),你会得到逻辑上预期的结果。跨度>
  • 这是完全可以预料的。在您认为应该是错误的查询中,子查询实际上是使用来自@DataTable 的 My_Id,而不是您认为的 MyId。这是一个经典示例,说明为什么用表(或最好是别名)引用每一列如此重要以避免此问题。

标签: sql-server sql-server-2014


【解决方案1】:

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

现在它会更有意义。

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

当使用exists 时,主要使用相关子查询。您可以在Where 子句中看到外部表中的列将被引用

【讨论】:

  • 当然这很有意义......但是当我看到一个更大的部分时,它通过我循环。今天早上不得不取下眼罩......
  • @DarianMiller - 完全有效的问题。我看到很多人提出了类似的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-18
  • 2013-07-26
  • 1970-01-01
相关资源
最近更新 更多