Sql-Server

排序和聯合所有

  • October 21, 2015

我有以下查詢:

SELECT  *
FROM    OPENQUERY([SERVERA],
   'SELECT ''SERVERA'',[PhoneNum]
   ,[PhoneExt]
   ,COUNT(2) as CNT
   FROM [DB].[dbo].[ResourcePhone] WHERE PhoneNum like ''+44%''
   OR PhoneNum like ''+41%''
   GROUP BY PhoneNum, PhoneExt
   HAVING COUNT(2) > 1;')
       UNION ALL
SELECT  *
FROM    OPENQUERY([SERVERB],
   'SELECT ''SERVERA'',[PhoneNum]
   ,[PhoneExt]
   ,COUNT(2) as CNT
   FROM [DB].[dbo].[ResourcePhone] WHERE PhoneNum like ''+44%''
   OR PhoneNum like ''+41%''
   GROUP BY PhoneNum, PhoneExt
   HAVING COUNT(2) > 1;')

我收到錯誤無法執行 varchar 值到 varchar 的隱式轉換,因為 UNION ALL 運算符中的“Latin1_General_CI_AS”和“SQL_Latin1_General_CP1_CI_AS”之間的排序規則衝突導致值的排序規則未解決。

我檢查了所涉及的列和數據庫的排序規則,它們都是Latin1_General_BIN. 區別在於SERVERA有一個排序規則SQL_Latin1_General_CP1_CI_ASSERVERB一個排序規則Latin1_General_CI_AS。我嘗試將 COLLATE 添加SQL_Latin1_General_CP1_CI_AS到列名,但這沒有奏效。

誰能建議如何解決這個問題?


添加了精確查詢

SELECT  *
FROM    OPENQUERY([SERVERA],
   'SELECT ''SERVERA'',resourcephone.[PhoneNum]
   ,resourcephone.[PhoneExt]
   ,COUNT(2) as CNT
   FROM [rtc].[dbo].[ResourcePhone] WHERE PhoneNum like ''+44%''
   OR PhoneNum like ''+41%''
   GROUP BY PhoneNum, PhoneExt
   HAVING COUNT(2) > 1;')
       UNION ALL
SELECT  *
FROM    OPENQUERY([SERVERB],
   'SELECT ''SERVERB'' COLLATE Latin1_General_CI_AS, resourcephone.[PhoneNum] COLLATE Latin1_General_CI_AS
   ,resourcephone.[PhoneExt] COLLATE Latin1_General_CI_AS
   ,COUNT(2) as CNT
   FROM [rtc].[dbo].[ResourcePhone] WHERE PhoneNum  like ''+44%''
   OR PhoneNum like ''+41%''
   GROUP BY PhoneNum, PhoneExt 
   HAVING COUNT(2) > 1;')

此查詢給出以下消息:

消息 457,級別 16,狀態 1,行 1 無法執行 varchar 值到 varchar 的隱式轉換,因為 UNION ALL 運算符中的“Latin1_General_CI_AS”和“Latin1_General_BIN”之間的排序規則衝突導致值的排序規則未解決。

問題應該出在字元串文字(即''SERVERA'')上,因為它採用了正在執行該語句的數據庫的排序規則。

因此,請在查詢的頂部嘗試以下操作:

SELECT  *
FROM    OPENQUERY([SERVERA],
   'SELECT ''SERVERA'' COLLATE Latin1_General_CI_AS, [PhoneNum]
...

UNION ALL而且, (用於的部分)的底部[SERVERB]可能應該選擇“SERVERB”而不是“SERVERA”作為字元串文字:)。

從技術上講,它採用數據庫的排序規則,而不是伺服器,但如果預設連接是到master(或任何系統數據庫),那麼這自然與伺服器級別的排序規則相同,因為伺服器- level Collat​​ion 用於創建系統 DB。

更新:

COLLATE將子句添加到中的第二個查詢後出現的新錯誤UNION ALL是由於將COLLATE子句添加到太多欄位。它只需要轉到文字字元串,而不是欄位resourcephone.[PhoneExt]。多做一步會使已經達成一致的領域陷入衝突。由於這兩個表欄位都在 中Latin1_General_BIN,因此無需resourcephone.[PhoneExt]從任一伺服器覆蓋欄位上的排序規則。只有字元串文字“欄位”需要被覆蓋,並且只能來自兩台伺服器之一:您**只需要使一個匹配另一個。

COLLATE子句添加到所有欄位,尤其是那些已經按預期工作的欄位(即resourcephone.[PhoneExt]欄位)是不必要的,並且會使查詢過於復雜。

引用自:https://dba.stackexchange.com/questions/118723