首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 2005 中文亂碼問題:排序規則設定完整解析

     編輯:關於SqlServer

專案上線後發現所有中文字元皆顯示為「????」,經排查資料寫入前正常,鎖定問題在資料庫層級。本文記錄從症狀到根因的完整診斷流程,並說明修改資料庫排序規則為何不足、必須連同資料行一併調整的關鍵細節。

現象與初步排查

  • 應用程式寫入資料前,中文編碼正確(UTF-8 / Big5 皆可)。
  • 資料落庫後,讀取時全部變成問號。
  • 檢視資料庫屬性 → 選項 → 排序規則,發現預設為 SQL_Latin1_General_CP1_CI_AS 等非中文友善規則。

錯誤嘗試:僅修改資料庫預設排序規則

將資料庫排序規則改為 Chinese_PRC_CI_AI(簡體拼音、不區分大小寫、不區分重音)後,僅部分新資料正常,舊資料與部份欄位仍亂碼。

根本原因:排序規則具有繼承機制,但不會回溯既有物件

  • 資料庫層級:僅影響之後建立的資料表、資料行預設排序規則。
  • 資料表層級:可覆寫資料庫預設,同樣僅影響之後新增的資料行。
  • 資料行層級:實際儲存與比較字串的單位,既有資料行不會自動變更。
  • 系統保留關鍵字、特定欄位(如範例中的 TrueName)可能因建立時指定了排序規則,導致不隨資料庫變更而更新。

完整修正步驟

方法一:透過 SSMS 圖形介面逐一修改(適合資料表較少)

  1. 資料庫屬性 → 選項 → 排序規則:改為 Chinese_PRC_CI_AI 或 Chinese_Taiwan_Stroke_CI_AI。
  2. 展開各資料表 → 資料行 → 右鍵「修改」 → 在資料行屬性視窗中,將每個 char/varchar/text/nchar/nvarchar/ntext 欄位的排序規則逐一改為目標規則。
  3. 儲存時若出現「防止儲存要求重建資料表」錯誤,請至 工具 → 選項 → 設計工具 取消勾選「防止儲存要求重建資料表的變更」。

方法二:T-SQL 指令碼批次產生 ALTER TABLE 語句(適合大量資料表)

DECLARE @TargetCollation SYSNAME = N'Chinese_PRC_CI_AI';
DECLARE @SQL NVARCHAR(MAX) = N'';

SELECT @SQL += N'
ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(t.schema_id)) + N'.' + QUOTENAME(t.name) + N'
ALTER COLUMN ' + QUOTENAME(c.name) + N' ' + 
    UPPER(TYPE_NAME(c.system_type_id)) + 
    CASE WHEN TYPE_NAME(c.system_type_id) IN (N'char', N'varchar', N'nchar', N'nvarchar')
         THEN N'(' + CASE WHEN c.max_length = -1 THEN N'MAX' ELSE CAST(c.max_length / CASE WHEN TYPE_NAME(c.system_type_id) LIKE N'n%' THEN 2 ELSE 1 END AS NVARCHAR(10)) END + N')'
         ELSE N'' END + 
    N' COLLATE ' + @TargetCollation + 
    CASE WHEN c.is_nullable = 1 THEN N' NULL' ELSE N' NOT NULL' END + N';'
FROM sys.tables t
JOIN sys.columns c ON c.object_id = t.object_id
WHERE t.is_ms_shipped = 0
  AND TYPE_NAME(c.system_type_id) IN (N'char', N'varchar', N'nchar', N'nvarchar', N'text', N'ntext')
  AND c.collation_name <> @TargetCollation;

-- PRINT @SQL; -- 先檢查
-- EXEC sp_executesql @SQL; -- 確認無誤後執行
注意:執行前請完整備份資料庫,且需考慮索引、外鍵、檢查條件約束等相依物件可能需先卸除再重建。

驗證與後續維護

  • 修改後,插入測試資料確認中文正常存取。
  • 檢視 sys.columns 確認所有字串欄位排序規則一致。
  • 新專案建立資料庫時,建議在 CREATE DATABASE 即指定 COLLATE Chinese_PRC_CI_AI,從源頭避免問題。

總結:資料庫排序規則只是「預設值」,真正決定字串儲存與比較行為的是資料行層級的排序規則。徹底解決亂碼,必須將現有所有字串欄位逐一修正至目標排序規則。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved