zoukankan      html  css  js  c++  java
  • 全库修改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

  • 相关阅读:
    137. Single Number II (Bit)
    136. Single Number (Bit)
    89. Gray Code (Bit)
    57. Insert Interval (Array; Sort)
    56. Merge Intervals (Array; Sort)
    UNIX 网络编程笔记-CH3:套接字编程简介
    UNIX 网络编程笔记-CH2:TCP、UDP概貌
    TSP-旅行商问题
    Java 集合:迭代器(Iterator, Iterable)
    PAT 1029. Median
  • 原文地址:https://www.cnblogs.com/fjzhang/p/11250019.html
Copyright © 2011-2022 走看看