Sql server 列前缀';%s';与查询中使用的表名或别名不匹配
我正在尝试对远程2000服务器运行查询;但是本地服务器生成的查询不正确,并导致远程服务器返回错误: 列前缀“Tbl1002”与查询中使用的表名或别名不匹配 跟踪远程服务器时,可以看到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
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
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。希望在那之前我们能忍受这次事故。