如何将整理更改为数据库的所有列?

问题描述 投票:34回答:7

我想更改数据库的所有表的所有列的排序规则。在堆栈溢出的其他帖子中我发现了这个脚本:(qazxsw poi)

post

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

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

为什么我可以更改数据库中所有表的所有列的排序规则?

谢谢。

sql-server collation
7个回答
75
投票

试试这个 -

查询:

SELECT 'ALTER TABLE [' + SYSOBJECTS.Name + '] ALTER COLUMN [' + SYSCOLUMNS.Name + '] ' +
SYSTYPES.name + 
    CASE systypes.NAME
    WHEN 'text' THEN ' '
    ELSE
    '(' + RTRIM(CASE SYSCOLUMNS.length
    WHEN -1 THEN 'MAX'
    ELSE CONVERT(CHAR,SYSCOLUMNS.length)
    END) + ') ' 
    END

    + ' ' + ' COLLATE Latin1_General__CI_AI ' + CASE ISNULLABLE WHEN 0 THEN 'NOT NULL' ELSE 'NULL' END
    FROM SYSCOLUMNS , SYSOBJECTS , SYSTYPES
    WHERE SYSCOLUMNS.ID = SYSOBJECTS.ID
    AND SYSOBJECTS.TYPE = 'U'
    AND SYSTYPES.Xtype = SYSCOLUMNS.xtype
    AND SYSCOLUMNS.COLLATION IS NOT NULL
    AND NOT ( sysobjects.NAME LIKE 'sys%' )
    AND NOT ( SYSTYPES.name LIKE 'sys%' )
    GO

输出:

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'

7
投票

我正在发布一个编辑上面的答案,它解决了char和varchar长度,因为我之前的编辑看起来像是被拒绝了。

-------------------------------------------------- ------------------------------------------------------------------------------------------------------------------
[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

6
投票

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

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'

2
投票

感谢大家的建议,它帮助我将数据库从SQL Server 2008 R2迁移到2014年

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

更改排序规则的步骤:

  1. 运行上面的查询并获取Alter表查询
  2. 删除表和表值函数的所有索引
  3. 运行步骤1的生成查询
  4. 创建表和表值函数的索引。

2
投票

虽然其他方法都不适合我,但/******************************************************************************* * * Created 2017-06-16 By Philip C * * This script will check individual columns collations and check it against the * database default collation, where they are different it will create the scripts * required to drop all the objects dependant on the column, change the collation * to the database default and then recreate the dependant objects. * Some of the code has been reused from stuff found online the majority from * Jayakumaur R who created scripts to drop and recreate constraints * *********************************************************************************/ SET ANSI_WARNINGS OFF; GO DECLARE @SchemaName VARCHAR(100); DECLARE @TableName VARCHAR(256); DECLARE @IndexName VARCHAR(256); DECLARE @ColumnName VARCHAR(100); DECLARE @is_unique VARCHAR(100); DECLARE @IndexTypeDesc VARCHAR(100); DECLARE @FileGroupName VARCHAR(100); DECLARE @is_disabled VARCHAR(100); DECLARE @IndexOptions VARCHAR(MAX); DECLARE @IndexColumnId INT; DECLARE @IsDescendingKey INT; DECLARE @IsIncludedColumn INT; DECLARE @TSQLScripCreationIndex VARCHAR(MAX); DECLARE @TSQLScripDisableIndex VARCHAR(MAX); DECLARE @Collation_objectid INT; DECLARE @Collation_columnid INT; DECLARE @Collation_constraint INT; DECLARE @Collation_index INT; DECLARE @Collation_foreign INT; DECLARE @Collation_stats INT; DECLARE @stats_id INT; DECLARE @Collation_fkid INT; DECLARE @Collation_unique INT; DECLARE @DatabaseCollation VARCHAR(100); CREATE TABLE #tempscriptstore (ScriptType VARCHAR(20), script NVARCHAR(MAX)); SELECT @DatabaseCollation=collation_name FROM sys.databases WHERE database_id=DB_ID(); /************************************************************************************************************************************ * Generates a list of all the columns where their collation doesn't match the database default and the depenmdancies they have. * ************************************************************************************************************************************/ DECLARE collationfix CURSOR FOR SELECT t.object_id, c.column_id, COUNT(kc.object_id) AS [has_key_constraint], COUNT(ic.index_id) AS [has_index], COUNT(fk.constraint_object_id) AS [has_foreign_key], COUNT(st.stats_id) AS [has_stats], COUNT(uq.object_id) AS [has_unique_constraint] FROM sys.columns c INNER JOIN sys.tables t ON c.object_id=t.object_id INNER JOIN sys.types ty ON c.system_type_id=ty.system_type_id LEFT JOIN sys.index_columns ic ON ic.object_id=c.object_id AND ic.column_id=c.column_id LEFT JOIN sys.key_constraints kc ON kc.parent_object_id=c.object_id AND kc.unique_index_id=ic.index_id AND kc.type='PK' LEFT JOIN sys.key_constraints uq ON uq.parent_object_id=c.object_id AND uq.unique_index_id=ic.index_id AND uq.type='UQ' LEFT JOIN sys.foreign_key_columns fk ON fk.referenced_object_id=c.object_id AND fk.constraint_column_id=c.column_id LEFT JOIN sys.stats_columns st ON st.object_id=c.object_id AND st.column_id=c.column_id AND st.stats_column_id !=1 WHERE t.is_ms_shipped=0 AND c.collation_name<>@DatabaseCollation AND ty.name !='sysname' GROUP BY t.object_id, c.column_id; OPEN collationfix; FETCH NEXT FROM collationfix INTO @Collation_objectid, @Collation_columnid, @Collation_constraint, @Collation_index, @Collation_foreign, @Collation_stats, @Collation_unique; WHILE(@@FETCH_STATUS=0)BEGIN /************************************************************************************************************************************ * Generates the code to update the columns colation * ************************************************************************************************************************************/ INSERT INTO #tempscriptstore(ScriptType, script) SELECT DISTINCT 'AlterCollation', 'ALTER TABLE '+QUOTENAME(t.name)+' ALTER COLUMN '+QUOTENAME(c.name)+' '+CASE WHEN ty.name='ntext' THEN ty.name+' COLLATE '+@DatabaseCollation+' ' ELSE ty.name+'('+CASE WHEN c.max_length=-1 THEN 'MAX' ELSE CASE WHEN ty.name='nvarchar' THEN CAST(c.max_length / 2 AS VARCHAR(20))ELSE CAST(c.max_length AS VARCHAR(20))END END+') COLLATE '+@DatabaseCollation+' ' END+CASE WHEN c.is_nullable=1 THEN 'NULL;' ELSE 'NOT NULL;' END FROM sys.columns c INNER JOIN sys.tables t ON c.object_id=t.object_id INNER JOIN sys.types ty ON c.system_type_id=ty.system_type_id LEFT JOIN sys.index_columns ic ON ic.object_id=c.object_id AND ic.column_id=c.column_id WHERE t.is_ms_shipped=0 AND c.collation_name<>@DatabaseCollation AND ty.name !='sysname' AND c.column_id=@Collation_columnid AND t.object_id=@Collation_objectid; /************************************************************************************************************************************ * If the column is in an index this creates the drop and recreate index script * ************************************************************************************************************************************/ IF @Collation_index>0 BEGIN DECLARE CursorIndex CURSOR FOR SELECT DISTINCT SCHEMA_NAME(t.schema_id) [schema_name], t.name, ix.name, CASE WHEN ix.is_unique=1 THEN 'UNIQUE ' ELSE '' END, ix.type_desc, CASE WHEN ix.is_padded=1 THEN 'PAD_INDEX = ON, ' ELSE 'PAD_INDEX = OFF, ' END+CASE WHEN ix.allow_page_locks=1 THEN 'ALLOW_PAGE_LOCKS = ON, ' ELSE 'ALLOW_PAGE_LOCKS = OFF, ' END+CASE WHEN ix.allow_row_locks=1 THEN 'ALLOW_ROW_LOCKS = ON, ' ELSE 'ALLOW_ROW_LOCKS = OFF, ' END+CASE WHEN INDEXPROPERTY(t.object_id, ix.name, 'IsStatistics')=1 THEN 'STATISTICS_NORECOMPUTE = ON, ' ELSE 'STATISTICS_NORECOMPUTE = OFF, ' END+CASE WHEN ix.ignore_dup_key=1 THEN 'IGNORE_DUP_KEY = ON, ' ELSE 'IGNORE_DUP_KEY = OFF, ' END+'SORT_IN_TEMPDB = OFF, FILLFACTOR ='+CASE WHEN ix.fill_factor=0 THEN CAST(100 AS VARCHAR(3))ELSE CAST(ix.fill_factor AS VARCHAR(3))END AS IndexOptions, ix.is_disabled, FILEGROUP_NAME(ix.data_space_id) FileGroupName FROM sys.tables t JOIN sys.indexes ix ON t.object_id=ix.object_id JOIN sys.columns c ON c.object_id=t.object_id JOIN sys.index_columns ic ON ic.index_id=ix.index_id AND ic.column_id=c.column_id AND ic.object_id=t.object_id WHERE ix.type>0 AND ix.is_primary_key=0 AND ix.is_unique_constraint=0 --AND schema_name(tb.schema_id)= @SchemaName --AND tb.name=@TableName AND t.is_ms_shipped=0 AND t.name<>'sysdiagrams' AND c.column_id=@Collation_columnid AND t.object_id=@Collation_objectid AND ic.column_id=@Collation_columnid ORDER BY SCHEMA_NAME(t.schema_id), t.name, ix.name; OPEN CursorIndex; FETCH NEXT FROM CursorIndex INTO @SchemaName, @TableName, @IndexName, @is_unique, @IndexTypeDesc, @IndexOptions, @is_disabled, @FileGroupName; WHILE(@@fetch_status=0)BEGIN DECLARE @IndexColumns VARCHAR(MAX); DECLARE @IncludedColumns VARCHAR(MAX); SET @IndexColumns=''; SET @IncludedColumns=''; DECLARE CursorIndexColumn CURSOR FOR SELECT col.name, ixc.is_descending_key, ixc.is_included_column FROM sys.tables tb INNER JOIN sys.indexes ix ON tb.object_id=ix.object_id INNER JOIN sys.index_columns ixc ON ix.object_id=ixc.object_id AND ix.index_id=ixc.index_id INNER JOIN sys.columns col ON ixc.object_id=col.object_id AND ixc.column_id=col.column_id WHERE ix.type>0 AND(ix.is_primary_key=0 OR ix.is_unique_constraint=0)AND SCHEMA_NAME(tb.schema_id)=@SchemaName AND tb.name=@TableName AND ix.name=@IndexName ORDER BY ixc.index_column_id; OPEN CursorIndexColumn; FETCH NEXT FROM CursorIndexColumn INTO @ColumnName, @IsDescendingKey, @IsIncludedColumn; WHILE(@@fetch_status=0)BEGIN IF @IsIncludedColumn=0 SET @IndexColumns=@IndexColumns+@ColumnName+CASE WHEN @IsDescendingKey=1 THEN ' DESC, ' ELSE ' ASC, ' END; ELSE SET @IncludedColumns=@IncludedColumns+@ColumnName+', '; FETCH NEXT FROM CursorIndexColumn INTO @ColumnName, @IsDescendingKey, @IsIncludedColumn; END; CLOSE CursorIndexColumn; DEALLOCATE CursorIndexColumn; SET @IndexColumns=SUBSTRING(@IndexColumns, 1, LEN(@IndexColumns)-1); SET @IncludedColumns=CASE WHEN LEN(@IncludedColumns)>0 THEN SUBSTRING(@IncludedColumns, 1, LEN(@IncludedColumns)-1)ELSE '' END; -- print @IndexColumns -- print @IncludedColumns INSERT INTO #tempscriptstore(ScriptType, script) SELECT 'DropIndex', 'DROP INDEX '+QUOTENAME(@SchemaName)+'.'+QUOTENAME(@TableName)+'.'+QUOTENAME(@IndexName)+';'; INSERT INTO #tempscriptstore(ScriptType, script) SELECT 'CreateIndex', 'CREATE '+@is_unique+@IndexTypeDesc+' INDEX '+QUOTENAME(@IndexName)+' ON '+QUOTENAME(@SchemaName)+'.'+QUOTENAME(@TableName)+'('+@IndexColumns+') '+CASE WHEN LEN(@IncludedColumns)>0 THEN CHAR(13)+'INCLUDE ('+@IncludedColumns+')' ELSE '' END+CHAR(13)+'WITH ('+@IndexOptions+') ON '+QUOTENAME(@FileGroupName)+';'; IF @is_disabled=1 INSERT INTO #tempscriptstore(ScriptType, script) SELECT 'DisableIndex', 'ALTER INDEX '+QUOTENAME(@IndexName)+' ON '+QUOTENAME(@SchemaName)+'.'+QUOTENAME(@TableName)+' DISABLE;'; FETCH NEXT FROM CursorIndex INTO @SchemaName, @TableName, @IndexName, @is_unique, @IndexTypeDesc, @IndexOptions, @is_disabled, @FileGroupName; END; CLOSE CursorIndex; DEALLOCATE CursorIndex; END; /************************************************************************************************************************************ * If the column has a primary key constraint this creates the drop and recreate constraint script * * this has been taken and adapted from a script found online created by Jayakumaur R * ************************************************************************************************************************************/ IF @Collation_constraint>0 BEGIN ------------------------------------------------- --ALTER TABLE DROP PRIMARY KEY CONSTRAINT Queries ------------------------------------------------- INSERT INTO #tempscriptstore(ScriptType, script) SELECT DISTINCT 'DropPrimaryKey', 'ALTER TABLE '+QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id))+'.'+QUOTENAME(OBJECT_NAME(parent_object_id))+' DROP CONSTRAINT '+QUOTENAME(name) FROM sys.key_constraints skc WHERE type='PK' AND parent_object_id=@Collation_objectid; --------------------------------------------------- --ALTER TABLE CREATE PRIMARY KEY CONSTRAINT Queries --------------------------------------------------- SELECT QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id))+'.'+QUOTENAME(OBJECT_NAME(parent_object_id)) AS pk_table, --PK table name skc.object_id AS constid, QUOTENAME(skc.name) AS constraint_name, --PK name QUOTENAME(iskcu.COLUMN_NAME)+CASE WHEN sic.is_descending_key=1 THEN ' DESC' ELSE ' ASC' END AS pk_col, iskcu.ORDINAL_POSITION, CASE WHEN unique_index_id=1 THEN 'UNIQUE' ELSE '' END AS index_unique_type, si.name AS index_name, si.type_desc AS index_type, QUOTENAME(fg.name) AS filegroup_name, 'WITH('+' PAD_INDEX = '+CASE WHEN si.is_padded=0 THEN 'OFF' ELSE 'ON' END+','+' IGNORE_DUP_KEY = '+CASE WHEN si.ignore_dup_key=0 THEN 'OFF' ELSE 'ON' END+','+' ALLOW_ROW_LOCKS = '+CASE WHEN si.allow_row_locks=0 THEN 'OFF' ELSE 'ON' END+','+' ALLOW_PAGE_LOCKS = '+CASE WHEN si.allow_page_locks=0 THEN 'OFF' ELSE 'ON' END+')' AS index_property --,* INTO #temp_pk FROM sys.key_constraints skc INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE iskcu ON skc.name=iskcu.CONSTRAINT_NAME INNER JOIN sys.indexes si ON si.object_id=skc.parent_object_id AND si.is_primary_key=1 INNER JOIN sys.index_columns sic ON si.object_id=sic.object_id AND si.index_id=sic.index_id INNER JOIN sys.columns c ON sic.object_id=c.object_id AND sic.column_id=c.column_id INNER JOIN sys.filegroups fg ON si.data_space_id=fg.data_space_id WHERE skc.type='PK' AND iskcu.COLUMN_NAME=c.name AND skc.parent_object_id=@Collation_objectid ORDER BY skc.parent_object_id, skc.name, ORDINAL_POSITION; WITH cte AS (SELECT pk_table, constraint_name, index_type, SUBSTRING((SELECT ','+pk_col FROM #temp_pk WHERE constid=t.constid FOR XML PATH('')), 2, 99999) AS pk_col_list, index_unique_type, filegroup_name, index_property FROM #temp_pk t) --forming the ADD CONSTRAINT query INSERT INTO #tempscriptstore(ScriptType, script) SELECT DISTINCT 'AddPrimaryKey', 'ALTER TABLE '+pk_table+' ADD CONSTRAINT '+constraint_name+' PRIMARY KEY '+CAST(index_type COLLATE DATABASE_DEFAULT AS VARCHAR(100))+' ('+pk_col_list+')'+index_property+' ON '+filegroup_name+'' FROM cte; --dropping the temp tables DROP TABLE #temp_pk; END; /************************************************************************************************************************************ * If the column has a foreign key constraint this creates the drop and recreate constraint script * * this has been taken and adapted from a script found online cretaed by Jayakumaur R * ************************************************************************************************************************************/ IF @Collation_foreign>0 BEGIN DECLARE foreignkeycursor CURSOR FOR SELECT constraint_object_id FROM sys.foreign_key_columns WHERE referenced_object_id=@Collation_objectid AND referenced_column_id=@Collation_columnid; OPEN foreignkeycursor; FETCH NEXT FROM foreignkeycursor INTO @Collation_fkid; WHILE(@@FETCH_STATUS=0)BEGIN --------------------------------------------- --ALTER TABLE DROP FOREIGN CONSTRAINT Queries --------------------------------------------- INSERT INTO #tempscriptstore(ScriptType, script) SELECT DISTINCT 'DropForeignKey', 'ALTER TABLE '+QUOTENAME(OBJECT_SCHEMA_NAME(fkeyid))+'.'+QUOTENAME(OBJECT_NAME(fkeyid))+' DROP CONSTRAINT '+QUOTENAME(OBJECT_NAME(constid)) FROM sys.sysforeignkeys sfk WHERE sfk.constid=@Collation_fkid; ------------------------------------------------ --ALTER TABLE CREATE FOREIGN CONSTRAINT Queries ------------------------------------------------ --Obtaining the necessary info from the sys tables SELECT constid, QUOTENAME(OBJECT_NAME(constid)) AS constraint_name, CASE WHEN fk.is_not_trusted=1 THEN 'WITH NOCHECK' ELSE 'WITH CHECK' END AS trusted_status, QUOTENAME(OBJECT_SCHEMA_NAME(fkeyid))+'.'+QUOTENAME(OBJECT_NAME(fkeyid)) AS fk_table, QUOTENAME(c1.name) AS fk_col, QUOTENAME(OBJECT_SCHEMA_NAME(rkeyid))+'.'+QUOTENAME(OBJECT_NAME(rkeyid)) AS rk_table, QUOTENAME(c2.name) AS rk_col, CASE WHEN fk.delete_referential_action=1 AND fk.delete_referential_action_desc='CASCADE' THEN 'ON DELETE CASCADE ' ELSE '' END AS delete_cascade, CASE WHEN fk.update_referential_action=1 AND fk.update_referential_action_desc='CASCADE' THEN 'ON UPDATE CASCADE ' ELSE '' END AS update_cascade, CASE WHEN fk.is_disabled=1 THEN 'NOCHECK' ELSE 'CHECK' END AS check_status --,sysfk.*,fk.* INTO #temp_fk FROM sys.sysforeignkeys sysfk INNER JOIN sys.foreign_keys fk ON sysfk.constid=fk.object_id INNER JOIN sys.columns c1 ON sysfk.fkeyid=c1.object_id AND sysfk.fkey=c1.column_id INNER JOIN sys.columns c2 ON sysfk.rkeyid=c2.object_id AND sysfk.rkey=c2.column_id WHERE sysfk.constid=@Collation_fkid ORDER BY constid, sysfk.keyno --building the column list for foreign/primary key tables ; WITH cte AS (SELECT DISTINCT constraint_name, trusted_status, fk_table, SUBSTRING((SELECT ','+fk_col FROM #temp_fk WHERE constid=c.constid FOR XML PATH('')), 2, 99999) AS fk_col_list, rk_table, SUBSTRING((SELECT ','+rk_col FROM #temp_fk WHERE constid=c.constid FOR XML PATH('')), 2, 99999) AS rk_col_list, check_status, delete_cascade, update_cascade FROM #temp_fk c) --forming the ADD CONSTRAINT query INSERT INTO #tempscriptstore(ScriptType, script) SELECT DISTINCT 'AddForeignKey', 'ALTER TABLE '+fk_table+' '+trusted_status+' ADD CONSTRAINT '+constraint_name+' FOREIGN KEY('+fk_col_list+') REFERENCES '+rk_table+'('+rk_col_list+')'+' '+delete_cascade+update_cascade+';'+' ALTER TABLE '+fk_table+' '+check_status+' CONSTRAINT '+constraint_name FROM cte; --dropping the temp tables DROP TABLE #temp_fk; FETCH NEXT FROM foreignkeycursor INTO @Collation_fkid; END; CLOSE foreignkeycursor; DEALLOCATE foreignkeycursor; END; /************************************************************************************************************************************ * If the column has statistics that aren't part of an index this creates the drop and recreate scripts * ************************************************************************************************************************************/ IF @Collation_stats>0 AND @Collation_index=0 BEGIN DECLARE stats_cursor CURSOR FOR SELECT sc.stats_id FROM sys.stats_columns sc JOIN sys.stats s ON s.object_id=sc.object_id AND s.stats_id=sc.stats_id AND s.user_created=1 WHERE sc.object_id=@Collation_objectid AND sc.column_id=@Collation_columnid; OPEN stats_cursor; FETCH NEXT FROM stats_cursor INTO @stats_id; WHILE(@@FETCH_STATUS=0)BEGIN --Create DROP Statistics Statement INSERT INTO #tempscriptstore(ScriptType, script) SELECT 'DropStatistics', 'DROP STATISTICS '+QUOTENAME(OBJECT_SCHEMA_NAME(s.object_id))+'.'+QUOTENAME(OBJECT_NAME(s.object_id))+'.'+QUOTENAME(s.name) FROM sys.stats s WHERE s.object_id=@Collation_objectid AND s.stats_id=@stats_id; --Building the CREATE statistics statement --Obtaining all the information SELECT QUOTENAME(OBJECT_SCHEMA_NAME(sc.object_id))+'.'+QUOTENAME(OBJECT_NAME(sc.object_id)) AS st_table, QUOTENAME(s.name) AS st_name, QUOTENAME(c.name) AS st_column, sc.object_id, sc.stats_id, sc.stats_column_id INTO #temp_stats FROM sys.stats_columns sc JOIN sys.stats s ON s.stats_id=sc.stats_id AND s.object_id=sc.object_id JOIN sys.columns c ON c.object_id=sc.object_id AND c.column_id=sc.column_id WHERE sc.object_id=@Collation_objectid AND sc.stats_id=@stats_id; WITH cte AS (SELECT DISTINCT st_table, st_name, SUBSTRING((SELECT ','+st_column FROM #temp_stats WHERE stats_id=ts.stats_id ORDER BY stats_column_id ASC FOR XML PATH('')), 2, 99999) AS st_col_list FROM #temp_stats ts) --Constructing the statement INSERT INTO #tempscriptstore(ScriptType, script) SELECT 'AddStatistics', 'CREATE STATISTICS '+cte.st_name+' ON '+cte.st_table+'('+cte.st_col_list+')' FROM cte; DROP TABLE #temp_stats; FETCH NEXT FROM stats_cursor INTO @stats_id; END; CLOSE stats_cursor; DEALLOCATE stats_cursor; END; /************************************************************************************************************************************ * If the column has a unique constraint this creates the drop and recreate scripts * ************************************************************************************************************************************/ IF @Collation_unique>0 BEGIN ------------------------------------------------- --ALTER TABLE DROP UNIQUE CONSTRAINT Queries ------------------------------------------------- INSERT INTO #tempscriptstore(ScriptType, script) SELECT DISTINCT 'DropUniqueKey', 'ALTER TABLE '+QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id))+'.'+QUOTENAME(OBJECT_NAME(parent_object_id))+' DROP CONSTRAINT '+QUOTENAME(name) FROM sys.key_constraints skc JOIN sys.index_columns ic ON ic.object_id=skc.parent_object_id AND ic.index_id=skc.unique_index_id WHERE type='UQ' AND parent_object_id=@Collation_objectid AND ic.column_id=@Collation_columnid; --------------------------------------------------- --ALTER TABLE CREATE UNIQUE CONSTRAINT Queries --------------------------------------------------- SELECT QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id))+'.'+QUOTENAME(OBJECT_NAME(parent_object_id)) AS uq_table, --PK table name skc.object_id AS constid, QUOTENAME(skc.name) AS constraint_name, --PK name QUOTENAME(iskcu.COLUMN_NAME)+CASE WHEN sic.is_descending_key=1 THEN ' DESC' ELSE ' ASC' END AS uq_col, iskcu.ORDINAL_POSITION, CASE WHEN unique_index_id=1 THEN 'UNIQUE' ELSE '' END AS index_unique_type, si.name AS index_name, si.type_desc AS index_type, QUOTENAME(fg.name) AS filegroup_name, 'WITH('+' PAD_INDEX = '+CASE WHEN si.is_padded=0 THEN 'OFF' ELSE 'ON' END+','+' IGNORE_DUP_KEY = '+CASE WHEN si.ignore_dup_key=0 THEN 'OFF' ELSE 'ON' END+','+' ALLOW_ROW_LOCKS = '+CASE WHEN si.allow_row_locks=0 THEN 'OFF' ELSE 'ON' END+','+' ALLOW_PAGE_LOCKS = '+CASE WHEN si.allow_page_locks=0 THEN 'OFF' ELSE 'ON' END+')' AS index_property --,* INTO #temp_uq FROM sys.key_constraints skc INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE iskcu ON skc.name=iskcu.CONSTRAINT_NAME INNER JOIN sys.indexes si ON si.object_id=skc.parent_object_id AND si.is_unique=1 INNER JOIN sys.index_columns sic ON si.object_id=sic.object_id AND si.index_id=sic.index_id INNER JOIN sys.columns c ON sic.object_id=c.object_id AND sic.column_id=c.column_id INNER JOIN sys.filegroups fg ON si.data_space_id=fg.data_space_id WHERE skc.type='UQ' AND iskcu.COLUMN_NAME=c.name AND skc.parent_object_id=@Collation_objectid AND c.column_id=@Collation_columnid ORDER BY skc.parent_object_id, skc.name, ORDINAL_POSITION; WITH cte AS (SELECT uq_table, constraint_name, index_type, SUBSTRING((SELECT ','+uq_col FROM #temp_uq WHERE constid=t.constid FOR XML PATH('')), 2, 99999) AS uq_col_list, index_unique_type, filegroup_name, index_property FROM #temp_uq t) --forming the ADD CONSTRAINT query INSERT INTO #tempscriptstore(ScriptType, script) SELECT DISTINCT 'AddUniqueKey', 'ALTER TABLE '+uq_table+' ADD CONSTRAINT '+constraint_name+' UNIQUE '+CAST(index_type COLLATE DATABASE_DEFAULT AS VARCHAR(100))+' ('+uq_col_list+')'+index_property+' ON '+filegroup_name+'' FROM cte; --dropping the temp tables DROP TABLE #temp_uq; END; FETCH NEXT FROM collationfix INTO @Collation_objectid, @Collation_columnid, @Collation_constraint, @Collation_index, @Collation_foreign, @Collation_stats, @Collation_unique; END; CLOSE collationfix; DEALLOCATE collationfix; /************************************************************************************************************************************ * Returns all the created scripts in the correct order for running * ************************************************************************************************************************************/ SELECT DISTINCT script, CASE WHEN ScriptType='DropForeignKey' THEN 1 WHEN ScriptType='DropPrimaryKey' THEN 2 WHEN ScriptType='DropUniqueKey' THEN 3 WHEN ScriptType='DropIndex' THEN 4 WHEN ScriptType='DropStatistics' THEN 5 WHEN ScriptType='AlterCollation' THEN 6 WHEN ScriptType='CreateIndex' THEN 7 WHEN ScriptType='DisableIndex' THEN 8 WHEN ScriptType='AddStatistics' THEN 9 WHEN ScriptType='AddUniqueKey' THEN 10 WHEN ScriptType='AddPrimaryKey' THEN 11 WHEN ScriptType='AddForeignKey' THEN 12 ELSE 99 END AS [exec_order] FROM #tempscriptstore WHERE script !='' ORDER BY exec_order ASC; DROP TABLE #tempscriptstore; 为我提供了一个完整的解决方案。我正在分享它,以防它帮助任何人。

  1. 创建所有数据库的备份。
  2. 停止服务器上的SQL Server服务。
  3. 打开命令提示符并导航到Binn目录,如

C:\ Program Files \ Microsoft SQL Server \ MSSQL11.MSSQLSERVER \ MSSQL \ Binn

  1. 执行以下命令以应用新的排序规则。

sqlservr -m -T4022 -T3659 -q“[输入排序规则名称]”

  1. 再次启动SQL Server服务。

而已。


1
投票

在执行此操作之前,请先阅读本文。 this article by Douglas P. Castilho

阅读上述文章后,请确保从数据库中删除了以下引用。

  • 计算列
  • 索引分布统计信息,可以自动生成,也可以由CREATE STATISTICS语句生成
  • 一个CHECK约束
  • 一个FOREIGN KEY约束

在此之后按下以下脚本,不要忘记更改数据库排序规则。

https://www.mssqltips.com/sqlservertip/3221/how-to-change-the-collation-of-a-sql-server-column/

0
投票

对于正在寻找使用PHPMyAdmin的此解决方案的任何人,在“数据库操作”选项卡的底部有一个选项(首先单击数据库,然后单击顶部工具栏上的“操作”选项卡);向下滚动到排序框,选择排序规则,选中两个复选框(选中第一个复选框时出现一个):

  • 更改所有表格排序
  • 更改所有表列的排序规则

似乎基本上运行像发布的脚本;控制台显示执行的最终命令:

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
© www.soinside.com 2019 - 2024. All rights reserved.