7

我们的应用程序中有两个表,它们都有一个ShowOrder列。我们在我们的应用程序中使用 NHibernate 并使用 HQL 我们将这两个表ShowOrder分别按第一个表和第二个表排序。

这是我的查询的简化版本:

SELECT pr.Id as Id,pr.Title as Title, pr.ShowOrder as ShowOrder 
FROM Process pr 
    INNER JOIN ProcessGroup prg ON pr.GroupId=prg.Id 
ORDER BY prg.ShowOrder,pr.ShowOrder

一般来说,我们的应用程序运行没有任何问题。但是我们有一个旧应用程序和一个转换例程,用于将其数据库转换为我们的新应用程序数据库。

每当我们将旧数据库转换为新数据库时,当 SQL 服务器要执行上述查询时,就会发生错误。异常说:

按列表的顺序多次指定了一个列

如果我们选择pr.ShowOrder不带别名,一切正常。

似乎如果ShowOrder选择列表中有别名,SQL Server 会忽略表别名并假定pr.ShowOrderprg.ShowOrder是相同的。

4

3 回答 3

12

这是 ANSI SQL 的标准行为,并且从 2005 版本开始被 SQL Server 采用。

ORDER BY 不对 Source 表(FROM 子句)中的列值进行操作,而是在技术上仅对 SELECT 子句(**)中的输出列值进行操作。因此,当您在 ORDER BY 子句中说“ShowOrder”时,它实际上是在使用输出列表中的 ShowOrder 值(恰好是 pr.ShowOrder)。如果您想同时使用这两个 ShowOrders,您应该将它们都放在 SELECT 子句中,并使用不同的名称。

当您使用源表别名(技术上应该这样做)时,它不会发出声音的原因是为了与 SQL Server 2000 兼容,但这是一种危险的兼容性。无论您在 ORDER BY 中使用什么别名,它实际上只使用出现在输出列表中的别名。

(** - 是的,有一些方法可以解决它,但它们主要是为了提供与以前版本的一些兼容性。你最好只使用标准)。

于 2009-09-02T11:37:49.207 回答
10

这是 SQL Server 2000 和 SQL Server 2005 之间的行为变化

http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/198b29db-f223-4aaf-a9f2-965c8a1fa8eb

于 2009-09-02T11:37:36.960 回答
2

此错误的另一个原因可能是 - 数据库兼容性级别设置为“ 2000-mode ”(这可能在您将 SQL Server 从 2000 升级到 2005 或更高版本后发生)。

解决方案:

“SQL Management Studio”——右键数据库——“属性”——“选项”——“兼容级别”——设置为90或更高。

于 2011-02-04T09:53:21.207 回答