此简单查询仅在一个数据库服务器上抛出“不明确的列名称TaskID”错误 。这是荒唐的。我们在不同的服务器和不同版本的SQL Server(2005/2008)上使用相同的数据库结构对此进行了测试,并且只有这个特定客户端的服务器才会抛出错误。我其实很沮丧。
SELECT Tasks.TaskID
FROM Tasks
INNER JOIN TaskHelpers ON TaskHelpers.TaskID = Tasks.TaskID
ORDER BY TaskID
是的,我知道我可以将Tasks.TaskID
放入order by
条款中,但由于某些原因我不能。{/ p>
答案 0 :(得分:11)
如果在sql server 2000上运行查询,或者在兼容级别80或更低级别下运行查询,则会出现模糊的列名错误。在兼容级别为90或更高的sql server 2005/2008上,您的查询运行正常。
来自order by子句docs:
“在SQL Server 2005中,限定的列名和别名将解析为FROM子句中列出的列。如果order_by_expression未限定,则该值必须在SELECT语句中列出的所有列中唯一。”
答案 1 :(得分:8)
我妈妈说总是在查询中使用表名/别名来限定每一列,就像“始终包含INSERT中的所有列名”一样,并且就像“不要选择*”等。
除了让它变得更容易,因为它是自我记录源代码,如果您添加/更改列,则可以防止此错误。
检查您的兼容性级别,它们之间存在差异以及ORDER BY的工作原理!
通常,在兼容级别90及更高级别,SQL Server 2008的默认级别,没有表名/别名语句的ORDER BY会产生错误。
ALTER DATABASE Compatibility Level (Transact-SQL)请参阅部分:兼容级别80和级别90之间的差异
兼容级别设置为80
WHEN绑定列引用时 列的ORDER BY列表 在SELECT列表列中定义 歧义被忽略和列 前缀有时会被忽略。这个 可以导致结果集返回 意外的订单。
例如,带有的ORDER BY子句 单个两部分专栏 (。)使用的 作为SELECT中列的引用 列表被接受,但表别名 被忽略了。考虑以下 查询。
SELECT c1 = -c1 FROM t_table AS x ORDER BY x.c1
执行时,列前缀为 在ORDER BY中被忽略。那种 操作不会发生 指定的源列(x.c1)为 预期;相反它发生在 派生的c1列,在中定义 查询。这个的执行计划 查询显示的值为 派生列首先计算和 然后对计算值进行排序。
兼容级别设置为90
列歧义引发错误。 列前缀(如果有),在中指定 绑定时不会忽略ORDER BY 到SELECT列表中定义的列。
请考虑以下问题。
SELECT c1 = -c1 FROM t_table AS x ORDER BY x.c1
执行时,列中的列前缀 ORDER BY子句不会被忽略。那种 操作发生在指定的源上 列(x.c1)如预期的那样。执行 此查询的计划显示排序 operator命令从t_table返回的行 然后是派生列的值 计算SELECT列表中定义的c1。
答案 2 :(得分:5)
您可以指定要排序的列的索引:
SELECT Tasks.TaskID
FROM Tasks
INNER JOIN TaskHelpers ON TaskHelpers.TaskID = Tasks.TaskID
order by 1
答案 3 :(得分:4)
哇。问题出在数据库兼容模式上。它被设置为“80”(sql 2000)。我已将其设置为90,现在查询工作正常。
有关兼容性级别的更多信息,请访问: http://msdn.microsoft.com/en-US/library/ms178653(SQL.90).aspx
答案 4 :(得分:1)
如果您尝试使用标识符怎么办?通过使用这些标识符,SQL Server知道要按哪个列排序。我从来没有以任何其他方式做过,从来没有遇到任何问题。我并不确切地说为什么sql需要这些标识符,显然他不知道在有不明确的列名的时候在哪里订购。尝试类似的事情;
SELECT t.TaskID
FROM Tasks t
INNER JOIN TaskHelpers th ON th.TaskID = t.TaskID
order by t.TaskID
编辑: 你不能的原因是什么? SQL抛出错误?
答案 5 :(得分:0)
你是什么意思不能?很明显,Tasks和TaskHelpers都有一个名为TaskID的列。您需要指明Order By中的列与哪个表相关联。