天天看點

全庫修改SQL Server現有排序規則

SQL Server備份還原後可能遇到排序規則不一緻的問題,此時通過統一排序規則可以解決。詳細操作如下:

資料庫報錯資訊:
無法解決 equal to 運算中 "SQL_Latin1_General_CP1_CI_AS" 和 "Chinese_PRC_CI_AS" 之間的排序規則沖突。
           
為解決排序規則沖突,可直接修改對應字段的排序規則,使其一緻則可避免查詢出錯,如下:
ALTER TABLE [表名] ALTER COLUMN [字段名] nvarchar(256) COLLATE Chinese_PRC_CI_AS'
           

但是資料庫中還有很多排序為“SQL_Latin1_General_CP1_CI_AS”的字段,如果逐個去改,幾個十幾個字段的話還可以考慮,要是幾十上百個工作量可想而知。我們可以先查詢目前資料庫的需要修改的字段,查詢對應的表名、字段名、排序規則、字段類型、以及對應的長度等等,如下:

SELECT
 t.name AS [Table],
 c.name AS [Column],
 c.collation_name AS [Collation],
 TYPE_NAME( c.system_type_id) AS [TypeName],
 c.max_length AS [TypeLength] 
FROM sys.columns c
 RIGHT JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.collation_name IS NOT NULL
           

執行上述語句,可能發現行數比較多,過多的修改量基本上是不可能手動去慢慢修改的,需要通過SQL查詢結果統一修改。部落格園網友推薦将結果集插入到臨時表中,在通過循環臨時表,exec執行拼接SQL語句去修改每一個記錄,具體代碼如下:

DECLARE @table NVARCHAR(128)--循環Item表名
DECLARE @column NVARCHAR(128)--循環Item字段名
DECLARE @type NVARCHAR(128)--對應字段的類型,char、nchar、varchar、nvarchar等
DECLARE @typeLenght NVARCHAR(128)--對應類型的長度,nchar、nvarchar需要将數值除于2
DECLARE @sql NVARCHAR(MAX )--要拼接執行的sql語句

 
SET ROWCOUNT 0

SELECT NULL mykey,
 c.name,
 t.name AS [Table],
 c.name AS [Column],
 c.collation_name AS [Collation],
 Type_name(c.system_type_id) AS [TypeName],
 c.max_length AS [TypeLength]
INTO #temp
FROM sys.columns c
 RIGHT JOIN sys.tables t
 ON c.object_id = t.object_id
WHERE c.collation_name IS NOT NULL
--先測試Product表
--AND t.name='Product'

SET ROWCOUNT 1
UPDATE #temp SET mykey = 1

WHILE @@ROWCOUNT > 0
 BEGIN
 SET ROWCOUNT 0

 --每次查詢第一條記錄并指派到對應變量中
 SELECT @table = [Table],
 @column = [Column],
 @type = TypeName,
 @typeLenght = TypeLength
 FROM #temp
 WHERE mykey = 1

 --nchar、nvarchar需要将數值除于2
 IF CONVERT(INT, @typeLenght) > 0 AND ( @type = 'nvarchar' OR @type = 'nchar' )
 BEGIN
 SET @typeLenght=CONVERT(NVARCHAR(128), CONVERT(INT, @typeLenght) / 2)
 END
 
 IF @typeLenght = '-1'
 BEGIN
 SET @typeLenght='max'
 END 

 --拼接sql,注意表名、字段名要帶[],避免Group等關鍵字
 SET @sql=' ALTER TABLE [' + @table + '] ALTER COLUMN ['
 + @column + '] ' + @type + '(' + @typeLenght
 + ') COLLATE Chinese_PRC_CI_AS'


 --Try執行
 BEGIN TRY
 EXEC(@sql)
 END TRY
 --Catch查詢異常結果
 BEGIN CATCH
 SELECT @sql AS [ASL],
 Error_message() AS msg
 END CATCH

 DELETE #temp
 WHERE mykey = 1

 SET ROWCOUNT 1

 UPDATE #temp
 SET mykey = 1
 END

SET ROWCOUNT 0

DROP TABLE #temp
           

執行SQL,更新出錯的try catch查詢結果顯示在清單中,我們可看到隻有寥寥的幾個字段需要通過手動去修改,這些修改不成功的大部分是由于外鍵關聯等原因,逐個排查即可。 至此,SQL已自動修改了大部分字段,大大的減少了工作量。

感謝原文作者: https://www.cnblogs.com/Ken-Blogs/p/6676006.html

轉載于:https://www.cnblogs.com/fjzhang/p/11250019.html