Sql server 如何将collate更改为数据库的所有列?

Sql server 如何将collate更改为数据库的所有列?,sql-server,collation,Sql Server,Collation,我想更改数据库中所有表的所有列的排序规则。在堆栈溢出中,我找到了以下脚本:() 但是,当我看到列的排序规则时,我看到排序规则是旧的排序规则 实际的排序是AS,所以我可以有“ANIMAL”和“ANIMAL”。当我执行脚本时,我没有得到任何错误。我想我会得到一个错误,因为新的排序规则是AI。这让我觉得剧本什么都没做 如何更改数据库中所有表的所有列的排序规则 谢谢。试试这个- 查询: DECLARE @collate SYSNAME SELECT @collate = 'Cyrillic_Genera

我想更改数据库中所有表的所有列的排序规则。在堆栈溢出中,我找到了以下脚本:()

但是,当我看到列的排序规则时,我看到排序规则是旧的排序规则

实际的排序是AS,所以我可以有“ANIMAL”和“ANIMAL”。当我执行脚本时,我没有得到任何错误。我想我会得到一个错误,因为新的排序规则是AI。这让我觉得剧本什么都没做

如何更改数据库中所有表的所有列的排序规则

谢谢。

试试这个-

查询:

DECLARE @collate SYSNAME
SELECT @collate = 'Cyrillic_General_CS_AS'

SELECT 
      '[' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + '] -> ' + c.name
    , 'ALTER TABLE [' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + ']
        ALTER COLUMN [' + c.name + '] ' +
        UPPER(t.name) + 
        CASE WHEN t.name NOT IN ('ntext', 'text') 
            THEN '(' + 
                CASE 
                    WHEN t.name IN ('nchar', 'nvarchar') AND c.max_length != -1 
                        THEN CAST(c.max_length / 2 AS VARCHAR(10))
                    WHEN t.name IN ('char', 'varchar') AND c.max_length != -1 
                        THEN CAST(c.max_length AS VARCHAR(10))
                    WHEN t.name IN ('nchar', 'nvarchar', 'char', 'varchar') AND c.max_length = -1 
                        THEN 'MAX'
                    ELSE CAST(c.max_length AS VARCHAR(10)) 
                END + ')' 
            ELSE '' 
        END + ' COLLATE ' + @collate + 
        CASE WHEN c.is_nullable = 1 
            THEN ' NULL'
            ELSE ' NOT NULL'
        END
FROM sys.columns c
JOIN sys.objects o ON c.[object_id] = o.[object_id]
JOIN sys.types t ON c.system_type_id = t.system_type_id AND c.user_type_id = t.user_type_id
WHERE t.name IN ('char', 'varchar', 'text', 'nvarchar', 'ntext', 'nchar')
    AND c.collation_name != @collate
    AND o.[type] = 'U'
-------------------------------------------------- ------------------------------------------------------------------------------------------------------------------
[dbo].[CategoryType] -> CategoryTypeCD          ALTER TABLE [dbo].[CategoryType] ALTER COLUMN [CategoryTypeCD] VARCHAR(20) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[Employee] -> TabelNumber                 ALTER TABLE [dbo].[Employee] ALTER COLUMN [TabelNumber] VARCHAR(12) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[Supplement] -> WorkFactorCD              ALTER TABLE [dbo].[Supplement] ALTER COLUMN [WorkFactorCD] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[Surcharge] -> WorkFactorCD               ALTER TABLE [dbo].[Surcharge] ALTER COLUMN [WorkFactorCD] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[Surcharge] -> Condition                  ALTER TABLE [dbo].[Surcharge] ALTER COLUMN [Condition] NVARCHAR(MAX) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[WorkFactor] -> WorkFactorCD              ALTER TABLE [dbo].[WorkFactor] ALTER COLUMN [WorkFactorCD] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[WorkFactor] -> Name                      ALTER TABLE [dbo].[WorkFactor] ALTER COLUMN [Name] NVARCHAR(200) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[WorkOut] -> WorkShiftCD                  ALTER TABLE [dbo].[WorkOut] ALTER COLUMN [WorkShiftCD] NVARCHAR(40) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[WorkOut] -> AbsenceCode                  ALTER TABLE [dbo].[WorkOut] ALTER COLUMN [AbsenceCode] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[WorkOut] -> PaymentType                  ALTER TABLE [dbo].[WorkOut] ALTER COLUMN [PaymentType] CHAR(4) COLLATE Cyrillic_General_CI_AS NULL
输出:

DECLARE @collate SYSNAME
SELECT @collate = 'Cyrillic_General_CS_AS'

SELECT 
      '[' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + '] -> ' + c.name
    , 'ALTER TABLE [' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + ']
        ALTER COLUMN [' + c.name + '] ' +
        UPPER(t.name) + 
        CASE WHEN t.name NOT IN ('ntext', 'text') 
            THEN '(' + 
                CASE 
                    WHEN t.name IN ('nchar', 'nvarchar') AND c.max_length != -1 
                        THEN CAST(c.max_length / 2 AS VARCHAR(10))
                    WHEN t.name IN ('char', 'varchar') AND c.max_length != -1 
                        THEN CAST(c.max_length AS VARCHAR(10))
                    WHEN t.name IN ('nchar', 'nvarchar', 'char', 'varchar') AND c.max_length = -1 
                        THEN 'MAX'
                    ELSE CAST(c.max_length AS VARCHAR(10)) 
                END + ')' 
            ELSE '' 
        END + ' COLLATE ' + @collate + 
        CASE WHEN c.is_nullable = 1 
            THEN ' NULL'
            ELSE ' NOT NULL'
        END
FROM sys.columns c
JOIN sys.objects o ON c.[object_id] = o.[object_id]
JOIN sys.types t ON c.system_type_id = t.system_type_id AND c.user_type_id = t.user_type_id
WHERE t.name IN ('char', 'varchar', 'text', 'nvarchar', 'ntext', 'nchar')
    AND c.collation_name != @collate
    AND o.[type] = 'U'
-------------------------------------------------- ------------------------------------------------------------------------------------------------------------------
[dbo].[CategoryType] -> CategoryTypeCD          ALTER TABLE [dbo].[CategoryType] ALTER COLUMN [CategoryTypeCD] VARCHAR(20) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[Employee] -> TabelNumber                 ALTER TABLE [dbo].[Employee] ALTER COLUMN [TabelNumber] VARCHAR(12) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[Supplement] -> WorkFactorCD              ALTER TABLE [dbo].[Supplement] ALTER COLUMN [WorkFactorCD] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[Surcharge] -> WorkFactorCD               ALTER TABLE [dbo].[Surcharge] ALTER COLUMN [WorkFactorCD] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[Surcharge] -> Condition                  ALTER TABLE [dbo].[Surcharge] ALTER COLUMN [Condition] NVARCHAR(MAX) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[WorkFactor] -> WorkFactorCD              ALTER TABLE [dbo].[WorkFactor] ALTER COLUMN [WorkFactorCD] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[WorkFactor] -> Name                      ALTER TABLE [dbo].[WorkFactor] ALTER COLUMN [Name] NVARCHAR(200) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[WorkOut] -> WorkShiftCD                  ALTER TABLE [dbo].[WorkOut] ALTER COLUMN [WorkShiftCD] NVARCHAR(40) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[WorkOut] -> AbsenceCode                  ALTER TABLE [dbo].[WorkOut] ALTER COLUMN [AbsenceCode] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[WorkOut] -> PaymentType                  ALTER TABLE [dbo].[WorkOut] ALTER COLUMN [PaymentType] CHAR(4) COLLATE Cyrillic_General_CI_AS NULL

我正在对上面的答案进行编辑,它解决了char和varchar长度问题,因为我之前的编辑看起来好像被拒绝了

DECLARE @collate SYSNAME
SELECT @collate = 'Cyrillic_General_CS_AS'

SELECT 
  '[' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + '] -> ' + c.name
, 'ALTER TABLE [' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + ']
    ALTER COLUMN [' + c.name + '] ' +
    UPPER(t.name) + 
    CASE WHEN t.name NOT IN ('ntext', 'text') 
        THEN '(' + 
            CASE 
                WHEN t.name IN ('nchar', 'nvarchar') AND c.max_length != -1 
                    THEN CAST(c.max_length / 2 AS VARCHAR(10))
                WHEN t.name IN ('char', 'varchar') AND c.max_length != -1 
                    THEN CAST(c.max_length AS VARCHAR(10))
                WHEN t.name IN ('nchar', 'nvarchar', 'char', 'varchar') AND c.max_length = -1 
                    THEN 'MAX'
                ELSE CAST(c.max_length AS VARCHAR(10)) 
            END + ')' 
        ELSE '' 
    END + ' COLLATE ' + @collate + 
    CASE WHEN c.is_nullable = 1 
        THEN ' NULL'
        ELSE ' NOT NULL'
    END
FROM sys.columns c WITH(NOLOCK)
    JOIN sys.objects o WITH(NOLOCK) ON c.[object_id] = o.[object_id]
    JOIN sys.types t WITH(NOLOCK) ON c.system_type_id = t.system_type_id AND c.user_type_id = t.user_type_id
WHERE t.name IN ('char', 'varchar', 'text', 'nvarchar', 'ntext', 'nchar')
    AND c.collation_name != @collate
    AND o.[type] = 'U'

感谢大家的建议,在将我的数据库从SQL Server 2008 R2迁移到2014的过程中,这对我帮助很大

注意:一些结果查询的VARCHAR(-)无效,我将其更改为VARCHAR(MAX),并且工作正常

更改排序规则的步骤:

  • 运行上述查询并获取ALTERTABLE查询
  • 删除表和表值函数的所有索引
  • 运行步骤1中生成的查询
  • 创建表和表值函数的索引

  • 虽然其他方法都不适用于我,但却为我提供了一个完整的解决方案。我正在分享它,以防它对任何人都有帮助

  • 创建所有数据库的备份
  • 停止服务器上的SQL Server服务
  • 打开命令提示符并导航到Binn目录,如
  • C:\Program Files\Microsoft SQL Server\MSSQLS11.MSSQLSERVER\MSSQL\Binn

  • 执行下面的命令以应用新的排序规则
  • sqlservr-m-T4022-T3659-q“[输入排序规则名称]”

  • 再次启动SQL Server服务

  • 就是这样。

    我从各种不同的来源收集了下面的脚本,删除依赖项更新排序规则,然后重新创建依赖项对象。这解决了更新具有依赖项(索引、外键约束等)的列的排序规则的问题

    /*******************************************************************************
    *
    *由Philip C.于2017年6月16日创建
    *分享时间:https://stackoverflow.com/questions/16730114/how-to-change-the-collate-to-all-the-columns-of-the-database/44587493#44587493
    *
    *此脚本将检查各个列的排序规则,并对照
    *数据库默认排序规则,如果它们不同,它将创建脚本
    *需要删除依赖于该列的所有对象时,请更改排序规则
    *设置为数据库默认值,然后重新创建从属对象。
    *一些代码已经从网上找到的东西中重新使用,这些东西大多数来自
    *Jayakumar,他创建了用于删除和重新创建约束的脚本
    *
    *Darren S为支持SQL2019而进行的次要编辑:替换和ty.name!='带和的sysname(类似于“%char%”的ty.Name或类似于“%text%”的ty.Name)
    *********************************************************************************/
    关闭ANSI_警告;
    去
    声明@SchemaName VARCHAR(100);
    声明@TableName VARCHAR(256);
    声明@IndexName VARCHAR(256);
    声明@ColumnName VARCHAR(100);
    声明@is_unique VARCHAR(100);
    声明@IndexTypeDesc VARCHAR(100);
    声明@FileGroupName VARCHAR(100);
    声明@is_已禁用VARCHAR(100);
    声明@IndexOptions VARCHAR(最大值);
    声明@IndexColumnId INT;
    声明@IsDescendingKey INT;
    声明@IsIncludedColumn INT;
    声明@TSQLScripCreationIndex VARCHAR(最大值);
    声明@TSQLScripDisableIndex VARCHAR(最大值);
    声明@Collation\u objectid INT;
    声明@Collation\u columnid INT;
    声明@Collation\u约束INT;
    声明@Collation\u index INT;
    声明@Collation\u foreign INT;
    声明@Collation\u stats INT;
    声明@stats_id INT;
    声明@Collation\u fkid INT;
    声明@Collation_unique INT;
    声明@DatabaseCollation VARCHAR(100);
    创建表#tempscriptstore(脚本类型VARCHAR(20),
    脚本NVARCHAR(最大值);
    选择@DatabaseCollation=collation\u名称
    从sys.databases
    其中数据库_id=DB_id();
    /************************************************************************************************************************************
    *生成排序规则与数据库默认值及其依赖项不匹配的所有列的列表*
    ************************************************************************************************************************************/
    声明的collationfix游标
    选择t.object\u id、c.column\u id、COUNT(kc.object\u id)作为[has\u key\u constraint],COUNT(ic.index\u id)作为[has\u index],COUNT(fk.constraint\u object\u id)作为[has\u foreign\u key],COUNT(st.stats\u id)作为[has\u stats],COUNT(uq.object\u id)作为[has\u unique\u constraint]
    来自sys.c列
    c.object\u id=t.object\u id上的内部联接sys.t表
    c.system\u type\u id=ty.system\u type\u id上的内部联接sys.types ty
    左连接ic上的sys.index\u列ic.object\u id=c.object\u id和ic.column\u id=c.column\u id
    左连接sys.key\u约束kc ON kc.parent\u object\u id=c.object\u id和kc.unique\u index\u id=ic.index\u id和kc.type='PK'
    左连接sys.key\u约束uq ON uq.parent\u object\u id=c.object\u id和uq.unique\u index\u id=ic.index\u id和uq.type='uq'
    左连接sys.foreign\u key\u列fk ON fk.引用的\u对象\u id=c.object\u id和fk.constraint\u列\u id=c.column\u id
    左键连接sys.stats\u columns st ON st.object\u id=c.object\u id和st.column\u id=c.column\u id和st.stats\u column\u id=1.
    其中t.is_ms_shipped=0和c.collation_name@DatabaseCollation和(类似于“%char%”的ty.Name或类似于“%text%”的ty.Name)
    按t.object\u id、c.column\u id分组;
    打开collationfix;
    从collationfix获取下一个
    分为@Collation\u objectid、@Collation\u columnid、@Collation\u constraint、@Collation\u index、@Collation\u foreign、@Collation\u stats、@Collation\u unique;
    当(@@FETCH\u STATUS=0)开始时
    /*******************************************************
    
    DECLARE @collate nvarchar(100);
    DECLARE @schema_name nvarchar(255);
    DECLARE @table_name nvarchar(255);
    DECLARE @column_name nvarchar(255);
    DECLARE @column_id int;
    DECLARE @data_type nvarchar(255);
    DECLARE @max_length int;
    DECLARE @is_nullable bit; 
    DECLARE @sql nvarchar(max);
    DECLARE @sql_column nvarchar(max);
    
    SET @collate = 'SQL_Latin1_General_CP1_CI_AS';
    
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
    
        DECLARE local_change_cursor CURSOR FOR
    
        SELECT SCHEMA_NAME(t.schema_id) schemaname,
              t.name table_name
            , c.name column_name
            , s.Name data_type
            , c.max_length
            , c.is_nullable
            , c.column_id 
      FROM sys.tables t INNER JOIN
           sys.columns c ON c.object_id=t.object_id INNER JOIN
           sys.types s ON s.user_type_id=c.user_type_id
     WHERE 
     (c.collation_name LIKE 'SQL_Latin1_General_CP1254_CI_AS' OR c.collation_name LIKE 'Turkish_CI_AS')  AND 
     t.type like 'U'
       AND t.name not like 'spt%'
       AND t.name not like 'MSrep%'
       AND c.collation_name is NOT NULL
    order by schemaname 
    
        OPEN local_change_cursor
        FETCH NEXT FROM local_change_cursor
        INTO @schema_name,@table_name, @column_name, @data_type, @max_length,@is_nullable, @column_id
    
        WHILE @@FETCH_STATUS = 0
        BEGIN
    
            DECLARE @nullable nvarchar(255),
                    @length   varchar(10);
    
            IF @is_nullable = 0
                BEGIN
                    SET @nullable = ' NOT NULL';
                END
            ELSE 
                BEGIN
                    SET @nullable = ' NULL';
                END
    
                IF @data_type IN ('nchar', 'nvarchar') AND @max_length != -1 
                    BEGIN
                        SET @length= CAST(@max_length / 2 AS VARCHAR(10));
                    END 
                ELSE IF @data_type IN ('char', 'varchar') AND @max_length != -1 
                    BEGIN
                        SET @length= CAST(@max_length AS VARCHAR(10));
                    END 
                ELSE IF @data_type IN ('nchar', 'nvarchar', 'char', 'varchar') AND @max_length = -1 
                    BEGIN
                        SET @length= 'MAX';
                    END 
                ELSE 
                    BEGIN
                        SET @length= CAST(@max_length AS VARCHAR(10));
                    END
    
            BEGIN TRY
                IF @schema_name <> 'dbo'
                    BEGIN
                        SET @sql = 'ALTER TABLE ['+ @schema_name +'].[' + @table_name + '] ALTER COLUMN [' + @column_name + '] ' + @data_type + '(' + @length + ') COLLATE ' + @collate + ''+ @nullable+' '
                        PRINT @sql
                        EXEC sp_executesql @sql
                    END
            END TRY
            BEGIN CATCH
                PRINT 'ERROR: Some index or constraint rely on the column' + @column_name + '. No conversion possible.'
                PRINT @sql
            END CATCH
    
            FETCH NEXT FROM local_change_cursor
            INTO @schema_name,@table_name, @column_name, @data_type, @max_length,@is_nullable, @column_id
    
        END
    
        CLOSE local_change_cursor
        DEALLOCATE local_change_cursor
    END
    
    GO
    
    ALTER TABLE `DB_NAME`.`LAST_TABLE_IN_DB`DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci