【问题标题】:SQL Server: joining a declared table variable with local server tablesSQL Server:将声明的表变量与本地服务器表连接起来
【发布时间】:2016-11-16 20:48:08
【问题描述】:

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

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 ON tbl2.foofield = @fooTable.foofield ; 

我收到一个错误:

必须声明标量变量“@fooTable”

我搜索了一下这个错误,我发现的大多数帖子都表明我试图访问的表超出了范围。

@fooTable 的声明以及 JOIN 查询是同一个存储过程的一部分,所以我找不到任何范围界定问题。

将变量表 (@fooTable) 与本地服务器中的表连接的最佳做法是什么? (tbl1, tbl2) ?

【问题讨论】:

  • 给表变量一个别名

标签: sql-server join


【解决方案1】:
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 ; 

【讨论】:

  • 你应该运行整个语句
【解决方案2】:

只需给表变量一个Alias 名称并使用它作为参考

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

【讨论】:

    【解决方案3】:

    您需要为表变量提供一个别名

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

    【讨论】:

      【解决方案4】:

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

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

      但是,SQL Server 没有采用 1992 年的连接类型,所以我们坚持使用 SQL 的原始解决方案,可以追溯到 1970 年代:范围变量。 [这里的其他人对同一概念使用了不恰当的术语“别名”。] 明确一点:用户需要使用范围变量来解决“通用名称”问题。

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

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-10
        • 1970-01-01
        • 2012-03-13
        • 1970-01-01
        相关资源
        最近更新 更多