SQL Server:将声明的表变量与本地服务器表连接

时间:2016-11-16 11:03:25

标签: sql-server join

我在存储过程中声明了一个表,即:

DECLARE @fooTable table ( idfoo INT)

INSERT INTO @fooTable
  EXEC getBOO 

SELECT * FROM @fooTable

我想将此表与本地服务器db中的其他表连接,即

SELECT *
FROM tbl1 
RIGHT JOIN tbl2 ON tbl1.foofield = tbl2.foofield
RIGHT JOIN @fooTable ON tbl2.foofield = @fooTable.foofield ; 

我收到错误:

  

必须声明标量变量" @ fooTable"

我已经搜索了一下这个错误,我发现的大部分帖子都说我试图触及的表格超出了范围。

@fooTable的声明以及JOIN查询是同一存储过程的一部分,因此我无法找到任何范围问题。

使用本地服务器中的表加入变量表(@fooTable)的最佳做法是什么? (tbl1,tbl2)?

4 个答案:

答案 0 :(得分:4)

DECLARE @fooTable table ( idfoo INT)
INSERT INTO @fooTable
EXEC getBOO 
SELECT * FROM @fooTable

SELECT *
FROM tbl1 RIGHT JOIN tbl2
ON tbl1.foofield = tbl2.foofield
RIGHT JOIN @fooTable f2
ON tbl2.foofield = f2.idfoo ; 

答案 1 :(得分:3)

只需为表变量指定一个Alias名称并将其用作参考

SELECT *
FROM   tbl1
       RIGHT JOIN tbl2
               ON tbl1.foofield = tbl2.foofield
       RIGHT JOIN @fooTable FT -- Here 
               ON tbl2.foofield = FT.foofield; 
                                --^^-- Here 

答案 2 :(得分:1)

您需要为表变量提供别名

SELECT *
FROM tbl1 RIGHT JOIN tbl2
ON tbl1.foofield = tbl2.foofield
RIGHT JOIN @fooTable FooTable
ON tbl2.foofield = FooTable.foofield; 

答案 3 :(得分:1)

这里的问题是两个表上的关系操作(连接),其中列具有相同的名称和类型。 1992年,当引入新的连接语法(NATURALUSING等)时,此问题得以解决。您的查询可以通过以下方式修复:

SELECT * 
  FROM tbl1 
      NATURAL RIGHT JOIN tbl2
      NATURAL RIGHT JOIN @fooTable;

但是,SQL Server还没有采用1992年的连接类型,所以我们坚持使用SQL的原始分辨率,可以追溯到20世纪70年代:范围变量。 [其他人在这里使用了不恰当的术语'别名'对于相同的概念。]要明确:用户必需使用范围变量来解析共同的名称'问题。

虽然您可能没有意识到,但您在代码中使用范围变量,例如在行

ON tbl1.foofield = tbl2.foofield

tbl1tbl2都是范围变量:每个变量代表其范围内的表的。因为你没有指定你自己的范围变量名,所以使用了表的名称(这也是它的根源于1970年代的SQL),即相当于:

SELECT *
 FROM tbl1 tbl1
      RIGHT JOIN tbl2 tbl2
         ON tbl1.foofield = tbl2.foofield

我猜你的代码落在哪里是@fooTable不是有效的范围变量名,即

  RIGHT JOIN @fooTable @fooTable

因此,修复方法是选择一个使SQL Server感到满意的范围变量名称,例如

SELECT *
  FROM tbl2 t2
       RIGHT JOIN @fooTable f
          ON t2.foofield  = f.foofield

我首选的解决方案是SQL Server实现1992连接类型!不在我的控制范围内,但我投了赞成票here