公司裡面使用的資料庫會有簡體中文和繁體中文兩種版本。我現在這個專案使用的SQLServer是繁體中文版的,但是需要使用到另一個使用簡體中文版SQLServer專案的資料,我按照通常的做法把簡體中文版SQLServer中的一個資料表匯入到現在使用的繁體中文版SQLServer中,結構和資料都匯入成功了。我一開始並沒有意識到這樣做會有什麼問題。接下來我開始調試SQL語句,其實是一個很簡單的兩表關聯資料選擇大致如下:
select table1.*,table2.*
from table1
inner join table2 on table2.FK = table1.PK
照理說這麼簡單的語句沒道理會出什麼問題,不過在查詢分析器裡面始終提示如下的錯誤
伺服器: 訊息 446,層級 16,狀態 9,行 1
無法解析 equal to 動作的定序衝突。
後來搜尋了一下,然後又看了一下T-SQL的協助,才知道原來是因為我將簡體中文SQL Server中的資料表匯入到繁體中文的資料表中的是後,連同原資料的排序方式一併匯入,導致了簡體資料表的排序方式依然是簡體,所以無法進行比較,從而出錯。解決的辦法是指名排序方式,告訴查詢分析器應該怎樣排序即可。這裡會需要用到一個關鍵字 COLLATE Coliate 在SQLServer聯機叢書中是這樣解釋的:
COLLATE
一個子句,可應用於資料庫定義或列定義以定義定序,或應用於字串運算式以應用定序投影。
文法:
COLLATE < collation_name >
< collation_name > ::=
{ Windows_collation_name } | { SQL_collation_name }
參數
collation_name
是應用於運算式、列定義或資料庫定義的定序的名稱。collation_name 可以只是指定的 Windows_collation_name 或 SQL_collation_name。
Windows_collation_name
是Windows 定序的定序名稱。請參見Windows定序名稱。
SQL_collation_name
是 SQL 定序的定序名稱。請參見 SQL 定序名稱。
那麼我們怎麼可以知道當前的定序名稱是什麼呢,其實這個定序名稱是我們在建立資料庫執行個體)的時候就可以進行選擇的,不過通常情況下我們都會預設原來的設定,不會對其進行變更,所以如果是簡體中文的SQLServer就會預設的使用簡體中文的定序,而如果是繁體中文的SQLServer就會預設的使用繁體中文的定序。我們在察看資料庫執行個體)的屬性時,常規頁簽的最下面一行就是當前的定序。在預設的情況下,簡體中文的定序名稱是:Chinese_PRC_CI_AS,而繁體中文的定序名稱則是:Chinese_Taiwan_Stroke_CI_AS,所以我們如果在有簡體繁體定序名稱混用的時候,只要聲明一下你當前要使用哪種定序進行比較就可以了,例如針對上面的那個SQL語句,下面兩種方法都可以解決那個錯誤提示的問題
SELECT Table1.*,Table2.*
FROM Table1
INNER JOIN Table2 ON Table2.FK = Table1.PK COLLATE Chinese_PRC_CI_AS
SELECT Table1.*,Table2.*
FROM Table1
INNER JOIN Table2 ON Table2.FK = Table1.PK COLLATE Chinese_Taiwan_Stroke_CI_AS
說了半天如何解決定序衝突引起的問題,如果還有興趣的話,下面把SQL Server聯機叢書裡面關於定序的概念貼出來給大家分享一下,省得大家再去找:
Microsoft® SQL Server™ 2000 支援多種定序。定序對控制正確使用語言如馬其頓語或波蘭語)或字母表如西歐語言使用的拉丁字母表 Latin1_General)字元的規則進行編碼。
每個 SQL Server 定序指定三個屬性:
用於 Unicode 資料類型nchar、nvarchar 和 ntext)的排序次序。排序次序定義字元的排序序列,以及在比較操作中對字元取值的方法。
用於非 Unicode 字元資料類型char、varchar 和 text)的排序次序。
用於儲存非 Unicode 字元資料的字碼頁。
說明 不能指定與 Unicode 資料類型nchar、nvarchar 和 ntext)對應的字碼頁。用於 Unicode 字元的雙位元組位元模式由 Unicode 標準定義且不能更改。
可在任何層級上指定 SQL Server 2000 定序。安裝 SQL Server 2000 執行個體時,可指定該執行個體的預設定序。每次建立資料庫時,可指定用於該資料庫的預設定序。如果未指定定序,資料庫的預設定序即是執行個體的預設定序。無論何時定義字元列、變數或參數,都可指定這些對象的定序。如果未指定定序,將使用資料庫的預設定序建立這些對象。
如果 SQL Server 執行個體的所有使用者都使用同一種語言,則應選擇支援該語言的定序。例如,若所有使用者都講法語,則選擇法語定序。
如果 SQL Server 執行個體的使用者使用多種語言,則應選擇能對多語種需求提供最佳支援的定序。例如,如果使用者一般都講西歐語言,則選擇 Latin1_General 定序。當支援使用多種語言的使用者時,對所有字元資料都使用 Unicode 資料類型 nchar、nvarchar 和 ntext 最為重要。Unicode 旨在消除非 Unicode char、varchar 和 text 資料類型的字碼頁轉換困難。因為定序定義用於比較操作的排序次序和 Unicode 字元的排序,所以當用 Unicode 資料類型實現所有的列時,定序仍會產生不同。即使當使用 Unicode 資料類型儲存字元資料時,也應選擇支援大多數使用者的定序,以防使用非 Unicode 資料類型實現列或變數。
SQL Server 定序定義資料庫引擎儲存和操作字元及 Unicode 資料的方式。然而,當資料移入應用程式後,在應用程式中進行的字元排序和比較將由電腦上選定的 Windows 地區設定控制。應用程式使用的字元資料定序是由 Windows 地區設定控制的項目之一,地區設定還定義其它項目,如數字、時間、日期和貨幣格式。對於 Microsoft Windows NT® 4.0、Microsoft Windows® 98 和 Microsoft Windows 95,可使用控制台中的"地區設定"應用程式指定 Windows 地區設定。對於 Microsoft Windows 2000,可使用"控制台"中的"地區選項"應用程式指定地區設定。有關 Windows 地區設定的更多資訊,請參見 Microsoft Web 網站 MSDN® 頁中的 Developing International Software for Windows 95 and Windows NT 4.0。
多個定序可對非 Unicode 資料使用相同的字碼頁。例如,字碼頁 1251 定義西裡爾語字元集。多個定序如 Cyrillic_General、Ukrainian 和 Macedonian)都使用該字碼頁。雖然這些定序都使用相同的位集來表示非 Unicode 字元資料,但在處理字典定義時所應用的排序和比較規則略有不同,而字典定義確定語言或字母表中與定序相關的正確字元序列。
因為SQL Server 2000定序控制 Unicode 和非 Unicode 排序次序,所以不會遇到由為 Unicode 和非 Unicode 資料指定不同的定序而引起的問題。在 SQL Server 的早期版本中,對字碼頁號、字元排序次序和 Unicode 定序分別進行指定。SQL Server 的早期版本還支援每個字碼頁有不同數目的排序次序,並為某些字碼頁提供 Windows 地區設定中沒有的排序次序。在 SQL Server 7.0 中,還可以指定為非 Unicode 資料選擇的排序次序以外的其它 Unicode 排序次序。這會導致在使用與非 Unicode 資料相對的 Unicode 資料時,排序和比較操作返回不同的結果。
- 在T-SQL中使用暫存資料表的注意事項
- SQL Server資料庫管理常用的SQL和T-SQL語句(1)
- 用T-SQL操作面試SQL Server開發人員(1)
- SQL Server 2005中的T-SQL
- T-SQL實用例句
- 微軟SQLServer密碼管理的危險判斷