2010-05-07 80 views
7

此簡單查詢在僅一個數據庫服務器上拋出「不明確列名稱TaskID」錯誤。這是荒唐的。我們在不同服務器和不同版本的SQL Server(2005/2008)上測試了相同的數據庫結構,並且只有這個特定客戶端的服務器引發了錯誤。我實際上感到沮喪。某個特定服務器上的「模糊列名稱」錯誤

SELECT Tasks.TaskID 
FROM Tasks 
INNER JOIN TaskHelpers ON TaskHelpers.TaskID = Tasks.TaskID 
ORDER BY TaskID 

是的,我知道我可以把Tasks.TaskIDorder by條款,但由於某些原因,我不能。

+1

我從來沒有想通了,爲什麼你要手動指定你指的是聯接的列之一。當然,如果他們加入,他們將會是一樣的!? (可能是一些奇怪的索引的東西,我不明白) – 2010-05-07 12:08:35

+0

聽起來很有趣(+1)。現在,有什麼問題? – Unreason 2010-05-07 12:24:04

+0

如果問題不會持續在其他服務器上,那麼也許你應該檢查SQL更新,或者一些設置可能? – Rob 2010-05-07 12:31:19

回答

4

哇。問題出在數據庫兼容模式。它被設置爲「80」(sql 2000)。我已將其設置爲90,現在查詢正常工作。

兼容性水平更多信息可以在這裏找到: http://msdn.microsoft.com/en-US/library/ms178653(SQL.90).aspx

+3

您更改了兼容性級別?沒有找出爲什麼這樣設置?非常糟糕的主意。你可能會破壞很多東西。除非您確信知道可以更改,否則請勿改變可編程性等級。如果有人在我們的服務器上這樣做了,他們會被解僱。 – HLGEM 2010-05-07 17:36:15

+0

@HLGEM歡迎來到諮詢世界。我們沒有改變它,客戶做了:( – Alex 2017-12-29 18:38:46

0

你是什麼意思,你不能?很明顯,Task和TaskHelpers都有一個名爲TaskID的列。您需要指出Order By中的列與哪個表相關聯。

5

您可以指定列的索引,而不是進行排序:

SELECT Tasks.TaskID 
FROM Tasks 
INNER JOIN TaskHelpers ON TaskHelpers.TaskID = Tasks.TaskID 
order by 1 
+0

爲什麼downvote?如果你不解釋你認爲什麼是錯的,它不能改善答案。 – Guffa 2014-02-25 17:43:19

+0

因爲答案是錯誤的。 SELECT'子句中有一個具有該名稱/別名的列,並且該名稱在'ORDER BY'中被引用時,不應該有錯誤。請參閱** [SQL-Fiddle](http://sqlfiddle.com/#!3/c16f95/1)**該錯誤是由於SQL-Server的某些舊版本/兼容級別中的錯誤,該錯誤已得到修復 – 2014-02-25 18:44:10

+0

@ypercube:看起來,SQL Server實際上是這樣做的,至少在更新的版本中。你有沒有參考*爲什麼*它這樣做?爲什麼選擇的字段用作訂單的默認字段? – Guffa 2014-02-25 18:55:05

1

如果您嘗試使用標識符什麼?通過使用這些標識符,SQL Server知道要排序的列。我從來沒有以任何其他方式做過,從來沒有任何問題。我不完全知道爲什麼sql需要這些標識符,很明顯他不知道在哪裏排序時,如果存在隱晦的列名。嘗試類似;編號: 你不能這樣做的原因是什麼? SQL拋出一個錯誤?

+0

不是的。實際上,我的前任構建了SQL-在多個業務邏輯操作中查詢代碼,並且問題中的查詢是查詢的非常簡化的版本...實際上具有子查詢,工會等功能 – Alex 2010-05-07 12:46:10

8

我的媽媽說:始終與表名/別名就像「始終在INSERT語句中的所有列名」查詢資格每一列和甫一像「不SELECT *」等

除了讓它更容易,因爲它是自我記錄源代碼,如果您添加/更改列,則可以防止出現此錯誤。

檢查您的兼容性級別,它們之間以及ORDER BY的工作方式有所不同!

通常,在兼容級別爲90或更高的SQL Server 2008的缺省級別中,沒有表名/別名語句的ORDER BY會產生錯誤。

ALTER DATABASE Compatibility Level (Transact-SQL)參見章節:兼容性等級80和電平之間的差異90

兼容性級的80

設置時結合在 的順序列引用BY列表中定義的列 在SELECT列表中,列 歧義被忽略,並且列 前綴有時會被忽略。此 可能導致結果集以 返回意外順序。

例如,ORDER BY子句與 單兩部分柱 (。)用於 作爲SELECT 列表的引用到列被接受,但表的別名 被忽略。考慮以下 查詢。

SELECT C1 = -c1 FROM t_table爲X ORDER BY x.c1

在執行時,列前綴是 在ORDER BY忽略。 操作在 指定的源列(x.c1)上沒有發生,因爲預期爲 ;而是發生在 導出的c1列中,該列在 中定義。此 查詢的執行計劃顯示首先計算 派生列的值,然後對所計算的值進行排序。

90個

錯誤兼容性級設置被升高上柱歧義。 將 綁定到SELECT列表中定義的列時,不會忽略在 ORDER BY中指定的列前綴(如果有)。

考慮以下查詢。

SELECT C1 = -c1 FROM t_table爲X ORDER BY x.c1

當被執行時,在 順序列前綴BY子句不忽略。如預期的那樣,在指定的源 列(x.c1)上發生 操作。該查詢的執行 計劃顯示,排序 運算符對從t_table 返回的行進行排序,然後計算SELECT列表中定義的派生列 c1的值。

+0

我很困惑。來自微軟網站的文字說,當級別爲80時,歧義被忽略,當級別爲90時,則引起歧義錯誤。但它轉向完全相反(檢查其他答案)。我對嗎? – natenho 2015-06-26 14:23:34

11

如果您在sql server 2000上運行查詢,或者在兼容級別爲80或更低的情況下,您將得到不明確的列名錯誤。在兼容級別爲90或更高的sql server 2005/2008上,yur查詢運行良好。

從ORDER BY子句文檔:

「在SQL Server 2005中,合格的列名和別名解析爲FROM子句中列出列如果order_by_expression的資格都沒有,其值必須是所有列中是唯一的。列在SELECT語句中。「

+0

是的,你是對的!雷,我們在一分鐘內發佈了相同的答案;) – Alex 2010-05-07 12:38:04

+0

偉大的思想...... :) – Ray 2010-05-07 12:41:56