Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 列前缀';%s';与查询中使用的表名或别名不匹配_Sql Server_Sql Server 2008 R2_Sql Server 2000_Correlated Subquery - Fatal编程技术网

Sql server 列前缀';%s';与查询中使用的表名或别名不匹配

Sql server 列前缀';%s';与查询中使用的表名或别名不匹配,sql-server,sql-server-2008-r2,sql-server-2000,correlated-subquery,Sql Server,Sql Server 2008 R2,Sql Server 2000,Correlated Subquery,我正在尝试对远程2000服务器运行查询;但是本地服务器生成的查询不正确,并导致远程服务器返回错误: 列前缀“Tbl1002”与查询中使用的表名或别名不匹配 跟踪远程服务器时,可以看到sp_cursorprepexec批处理实际上是无效的SQL;它引用了一个不存在的dervied表Tbl1002 我在本地服务器上运行的查询是: SELECT P.Code, P.Name AS PositionName, P.CompCommitteeMember, ( SELECT COUN

我正在尝试对远程2000服务器运行查询;但是本地服务器生成的查询不正确,并导致远程服务器返回错误:

列前缀“Tbl1002”与查询中使用的表名或别名不匹配

跟踪远程服务器时,可以看到
sp_cursorprepexec
批处理实际上是无效的SQL;它引用了一个不存在的dervied表
Tbl1002

我在本地服务器上运行的查询是:

SELECT
    P.Code, P.Name AS PositionName, P.CompCommitteeMember,
    (    SELECT COUNT(*) 
         FROM Employees E 
         WHERE E.PositionID = P.PositionID
    ) AS EmployeeCount
FROM Positions P
WHERE P.PositionID = '{D1B0912D-B1A5-11D4-BBDD-0004ACC5B8A7}' 
其中
Employees
Positions
是仅从链接服务器中选择的视图。为了消除这种混淆,我们将消除视图,并直接使用四部分命名:

SELECT
    P.Code, P.Name AS PositionName, P.CompCommitteeMember,
    (    SELECT COUNT(*) 
         FROM WCLHR.CasinoHR.dbo.Employees E 
         WHERE E.PositionID = P.PositionID
    ) AS EmployeeCount
FROM WCLHR.CasinoHR.dbo.Positions P
WHERE P.PositionID = '{D1B0912D-B1A5-11D4-BBDD-0004ACC5B8A7}' 
查询仍然失败,原因是:

列前缀“Tbl1002”与查询中使用的表名或别名不匹配

为了消除
WHERE
子句中guid的任何混淆,我们将消除
WHERE
子句:

SELECT
    P.Code, P.Name AS PositionName, P.CompCommitteeMember,
    (    SELECT COUNT(*) 
         FROM WCLHR.CasinoHR.dbo.Employees E 
         WHERE E.PositionID = P.PositionID
    ) AS EmployeeCount
FROM WCLHR.CasinoHR.dbo.Positions P
但它仍然在以下方面失败:

列前缀“Tbl1002”与查询中使用的表名或别名不匹配

为了避免在
计数
中使用
*
时出现任何混淆,我们将消除它,而只计算一个常量:

SELECT
    P.Code, P.Name AS PositionName, P.CompCommitteeMember,
    (    SELECT COUNT(1) 
         FROM WCLHR.CasinoHR.dbo.Employees E 
         WHERE E.PositionID = P.PositionID
    ) AS EmployeeCount
FROM WCLHR.CasinoHR.dbo.Positions P
但它仍然在以下方面失败:

列前缀“Tbl1002”与查询中使用的表名或别名不匹配

进一步,我们甚至将消除链接的服务器,并在2000机器上本地运行查询

如果在远程服务器上运行它会怎么样? 如果我对远程服务器本身运行此查询:

SELECT
    P.Code, P.Name AS PositionName, P.CompCommitteeMember,
    (    SELECT COUNT(*) 
         FROM Employees E 
         WHERE E.PositionID = P.PositionID
    ) AS EmployeeCount
FROM Positions P
它很好用

生成的查询是什么,您如何知道它是坏的? 使用探查器,我们可以看到查询进入远程服务器。这是一个巨大的可怕的混乱,但它肯定是无效的。它尝试引用不在范围内的派生表。在SQL Server中使用过远程服务器的任何人都会熟悉整个批次:

declare @P1 int
set @P1=NULL
declare @P2 int
set @P2=NULL
declare @P3 int
set @P3=557064
declare @P4 int
set @P4=98305
declare @P5 int
set @P5=0
exec sp_cursorprepexec @P1 output, @P2 output, NULL, N'SELECT "Tbl1002"."PositionID", .....
select @P1, @P2, @P3, @P4, @P5
真正的问题是另一台SQL服务器要求服务器准备的SQL语句。删减,它说:

SELECT 
   "Tbl1002"."PositionID" "Col1010", ...
   (   SELECT "Expr1007" 
       FROM (
          SELECT "Expr1006","Expr1006" "Expr1007" 
          FROM (
             SELECT COUNT(*) "Expr1006" 
             FROM (
                SELECT 
                   "Tbl1005"."EmployeeID" "Col1043", ...
                FROM "CasinoHR"."dbo"."Employees" "Tbl1005" 
                WHERE "Tbl1005"."PositionID"="Tbl1002"."PositionID"
             ) Qry1103
          ) Qry1104
       ) "Subquery_Source_Tbl" 
    ) "Expr1008" 
FROM "CasinoHR"."dbo"."Positions" "Tbl1002" 
WHERE "Tbl1002"."PositionID"={guid'D1B0912D-B1A5-11D4-BBDD-0004ACC5B8A7'}'
这是一个混乱的读取,但您可以看到问题,它在一些嵌套的派生表中引用了
Tbl1002

WHERE "Tbl1005"."PositionID"="Tbl1002"."PositionID"
但只是在外面宣布;最后:

FROM "CasinoHR"."dbo"."Positions" "Tbl1002"  
我们在这里讨论的是什么版本的SQL Server? 我们试图查询的“远程”服务器(“wclhr”)是带有SP4的SQL server 2000:

Microsoft SQL Server 2000-8.00.2066(英特尔X86)2012年5月11日18:41:14

在发出查询时,我们尝试使用SQLServer2005和SQLServer2008R2。当两台服务器都是SQLServer2000时,它就可以工作了

从SQL Server 2005开始,一直到2008 R2,它正在生成无效的SQL

我们尝试过的其他事情 令人惊讶的是,一个可怕的黑客正在运行:

SELECT TOP 99.999999 PERCENT
    P.Code, P.Name AS PositionName, P.CompCommitteeMember,
    (    SELECT COUNT(1) 
         FROM WCLHR.CasinoHR.dbo.Employees E 
         WHERE E.PositionID = P.PositionID
    ) AS EmployeeCount
FROM WCLHR.CasinoHR.dbo.Positions P
这将阻止本地SQL Server 2008 R2为2000计算机生成无效SQL

本地服务器不是64位的,但我们可以。它没有解决它

您最初的查询不也是错误的吗? @不相信的达米恩不相信范围界定是个问题。请放心,是的。我的原始查询在SQL Server 2000上正确运行:

SELECT
    P.Code, P.Name AS PositionName, P.CompCommitteeMember,
    (    SELECT COUNT(*) 
         FROM Employees E 
         WHERE E.PositionID = P.PositionID
    ) AS EmployeeCount
FROM Positions P
WHERE P.PositionID = '{D1B0912D-B1A5-11D4-BBDD-0004ACC5B8A7}' 
不幸的是,SQL Server 2005/2008/2008R2优化器将该查询转换为等效查询,但不幸的是,SQL Server 2000无法执行该查询:

SELECT 
   Tbl1002.PositionID, 
   Tbl1002.Name AS PositionName, 
   Tbl1002.CompCommitteeMember,
   (    SELECT RecordCount
        FROM (
            SELECT COUNT(*) AS RecordCount
            FROM (
                SELECT 
                    Employees.EmployeeID
                FROM Employees
                WHERE Employees.PositionID=Tbl1002.PositionID
            ) Qry1103
        ) Qry1104
    ) AS EmployeeCount
FROM Positions Tbl1002
WHERE Tbl1002.PositionID= 'D1B0912D-B1A5-11D4-BBDD-0004ACC5B8A7'
在SQL Server 2000上,它提供:

Msg 107, Level 16, State 2, Line 12
The column prefix 'Tbl1002' does not match with a table name or alias name used in the query.
SQL Server 2000似乎存在与相关子查询相关的作用域问题;这在SQLServer2005中得到了“改进”

额外阅读
  • Microsoft Connect:

根据您所附的阅读资料,要真正解决此问题,您需要重新构造查询,以避免链接服务器上的相关子查询

一种可能是将链接表作为联接包含在分组select中,并计算该语句中的聚合计数

SELECT
    P.Code, P.Name AS PositionName, P.CompCommitteeMember, Count(*)
FROM Positions P
Left Join Employees E on E.PositionID = P.PositionID
WHERE P.PositionID = '{D1B0912D-B1A5-11D4-BBDD-0004ACC5B8A7}' 
group by P.Code, P.Name, P.CompCommitteeMember

您是否尝试使用
OPENQUERY
而不是直接使用四部分命名?显示2005/2008服务器上2000服务器的LinkedServer设置。查看查询,它不能更改为
E.PositionID='{D1B0912D-B1A5-11D4-BBDD-0004ACC5B8A7}'
?考虑到外部查询查找特定位置ID的事实,为什么在子查询中使用
JOIN
?我不理解您关于“只在外部声明它”的观点;最后:“-在您在相关子查询中引用
P
的原始查询中不完全相同,但您只“声明”它出现在你的
FROM
子句的末尾?@Damien\u不信者你是对的。我的查询在2000机器上以本机方式运行时运行良好。当在2000机器上本机运行时,2005机器生成的远程查询失败。接受“尝试重新编写查询以绕过优化器错误”。他们计划在5到6个月内将该服务器升级到2008 R2。希望在那之前我们能忍受这次事故。