Как изменить сопоставление для всех столбцов базы данных?

Я хотел бы изменить параметры сортировки всех столбцов всех таблиц в моей базе данных. В другом посте в переполнении стека я нашел этот скрипт: ( пост)

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

Однако, когда я вижу параметры сортировки столбцов, я вижу, что параметры сортировки - это старые параметры сортировки.

Фактическое сопоставление - AS, поэтому у меня могут быть "ANIMAL" и "ÁNIMAL". Когда я выполняю скрипт, я не получаю никакой ошибки. Я думаю, что я получил бы ошибку, потому что новое сопоставление - ИИ. Так что это заставляет меня думать, что сценарий ничего не делает.

Почему я могу изменить параметры сортировки всех столбцов всех моих таблиц в базе данных?

Благодарю.

10 ответов

Решение

Попробуй это -

Запрос:

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

Я собрал приведенный ниже скрипт из различных источников, которые удаляют зависимости, обновляют параметры сортировки, а затем воссоздают зависимые объекты. Это решает проблему обновления сортировки столбцов, которые имеют зависимости (индексы, ограничения внешнего ключа и т. Д.)

            /*******************************************************************************
            *
            * 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;

Я публикую правку в ответе выше, которая касается длины символов и 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'

Хотя ни один из других подходов не помог мне, эта статья Дугласа П. Кастильо дала мне полное решение. Я делюсь этим на случай, если это кому-нибудь поможет.

  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 снова.

Вот и все.

Спасибо всем за предложение, оно мне очень помогло при переносе моей базы данных с SQL Server 2008 R2 на 2014

ПРИМЕЧАНИЕ. Некоторые из приведенных запросов имеют недопустимый VARCHAR(-), я изменил его на VARCHAR(MAX), и он работает нормально.

Шаги, чтобы изменить параметры сортировки:

  1. Запустите вышеуказанный запрос и получите запрос Alter table
  2. Удалить все индексы таблиц и табличных функций
  3. Запустите сгенерированный запрос шага 1
  4. Создание индексов таблиц и табличных функций.

Для тех, кто ищет это решение и использует PHPMyAdmin, есть опция внизу вкладки "Операции с базами данных" (сначала нажмите на базу данных, затем на вкладку "операции" на верхней панели инструментов); прокрутите вниз до поля сортировки, выберите параметры сортировки, отметьте два флажка (один из них появляется, когда отмечен первый):

  • Изменить все таблицы сопоставлений
  • Изменить все таблицы столбцов сопоставления

Похоже, что в основном запустить скрипт, как те, которые опубликованы консоль показывает последнюю выполненную команду:

ALTER TABLE `DB_NAME`.`LAST_TABLE_IN_DB`DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci

Перед выполнением этой операции, пожалуйста, сначала прочтите эту статью. https://www.mssqltips.com/sqlservertip/3221/how-to-change-the-collation-of-a-sql-server-column/

Прочитав вышеуказанную статью и убедитесь, что вы удалили ниже ссылки из вашей базы данных.

  • Вычисляемый столбец
  • Статистика распределения индекса, генерируемая автоматически или оператором CREATE STATISTICS
  • Ограничение CHECK
  • ИНОСТРАННОЕ КЛЮЧЕВОЕ ограничение

Нажмите на приведенный ниже скрипт в вашей базе данных, после чего не забудьте изменить также сортировку базы данных.

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

Первая часть

Примечание. Это не мое решение, это сборник комментариев, которые сработали для меня с этой страницы https://sqlserverfast.com/blog/hugo/2019/01/collation-change-script/.

      /*******************************************************************************
*
* 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
*
*
* Modified 2019-01-11 by Hugo Kornelis
*
* Removed double checking of recreated constraints
* Modified the order of the output to minimize number of index rebuilds (assuming primary key is most often clsutered index)
* Fixed a bug caused by unique constraints overlapping the primary key constraint
* Fixed a bug in detection of foreign key constraints to drop and recreate
* Fixed bugs with recreating multi-column UNIQUE constraints
*
* Modified 2019-08-12 by Walter Charrière
*
* Add drop and create default constraints
* Fixed bug with text columns adding length
* Add Where calusule for filtered indexes
*
* Modified 2019-12-19 by Damon Clark
*
* Added fix from Erland for doubling length of nchar columns
* Added quoting of column names in create index statements (for reserved words)
*
* Modified 2022-11-14 by Fernan2
* Added Darren Rhymer check constraint drop and create
* 
************************************************************************************/

SET NOCOUNT ON;
    SET ANSI_WARNINGS OFF;
    GO
    
    -- Declare variables
    DECLARE @SchemaName sysname,
    @TableName sysname,
    @IndexName sysname,
    @ColumnName sysname,
    @index_id int,
    @is_unique nvarchar(100),
    @IndexTypeDesc nvarchar(100),
    @FileGroupName sysname,
    @is_disabled nvarchar(100),
    @IndexOptions nvarchar(MAX),
    @IndexColumnId int,
    @IsDescendingKey int,
    @IsIncludedColumn int,
    @TSQLScripCreationIndex nvarchar(MAX),
    @TSQLScripDisableIndex nvarchar(MAX),
    @object_id int,
    @has_key_constraint int,
    @has_index int,
    @has_foreign_key int,
    @has_stats int,
    @stats_id int,
    @FK_objectid int,
    @FK_name sysname,
    @UQ_objectid int,
    @UQ_name sysname,
    @UQ_index_id int,
    @has_unique_constraint int,
    @has_default_constraint int,
    @has_check_constraint int,
    @DatabaseCollation sysname,
    @IndexColumns nvarchar(MAX),
    @IncludedColumns nvarchar(MAX),
    @filter_definition nvarchar(MAX);
    
    -- Temporary table for generated script
    CREATE TABLE #tempscriptstore
    (ScriptType varchar(20),
    script nvarchar(MAX));
    
    -- Get dataabse default collation
    SELECT @DatabaseCollation = collation_name
    FROM sys.databases
    WHERE database_id = DB_ID();
    
    /************************************************************************************************************************************
    * Iterate over all the tables that have at least one colmun where collation doesn't match the database default. *
    * Also checks for PRIMARY KEY, UNIQUE, and (referencing) FOREIGN KEY constraints, indexes, and manually created statistics. *
    * (Note that the counts are not accurate counts due to duplication, these should only be tested for zero or non-zero) *
    ************************************************************************************************************************************/
    DECLARE collationfix CURSOR LOCAL FORWARD_ONLY READ_ONLY STATIC FOR
    SELECT t.object_id,
    OBJECT_SCHEMA_NAME(t.object_id) AS schemaname,
    OBJECT_NAME(t.object_id) AS tablename,
    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,
    COUNT(dc.object_id) AS has_default_constraint,
    count(cc.object_id) as has_check_constraint
    FROM sys.tables AS t
    INNER JOIN sys.columns AS c
    ON c.object_id = t.object_id
    AND c.collation_name <> @DatabaseCollation -- Table needs to have columns with “wrong” collation
    INNER JOIN sys.types AS ty
    ON ty.system_type_id = c.system_type_id
    AND ty.name <> N'sysname' -- Exclusion retained from Philip C's original script
    LEFT JOIN sys.index_columns AS ic -- Find indexes on any of the affected columns
    ON ic.object_id = c.object_id
    AND ic.column_id = c.column_id
    LEFT JOIN sys.key_constraints AS kc -- Find primary key constraints related to an affected index
    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 AS uq -- Find unique constraints related to an affected index
    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 AS fk -- Find foreign key constraints on any of the affected columns
    ON fk.parent_object_id = c.object_id
    AND fk.parent_column_id = c.column_id
    LEFT JOIN sys.stats_columns AS st -- Find statistics on any of the affected columns
    ON st.object_id = c.object_id
    AND st.column_id = c.column_id
    AND st.stats_column_id <> 1 -- Retained from Philip C's original script, no idea why this is in the query
    LEFT JOIN sys.default_constraints AS dc -- Find default constraints on any of the affected columns
    ON dc.object_id = c.default_object_id
    AND dc.parent_column_id = c.column_id
    LEFT JOIN sys.check_constraints AS cc -- Find check_constraints on any of the affected columns
    ON cc.parent_object_id = c.object_id
    AND cc.parent_column_id = c.column_id
    
    WHERE t.is_ms_shipped = 0 -- Exclude Microsoft-shipped tables
    
    GROUP BY t.object_id
    --order by 3
    
    OPEN collationfix;
    FETCH NEXT FROM collationfix
    INTO @object_id,
    @SchemaName,
    @TableName,
    @has_key_constraint,
    @has_index,
    @has_foreign_key,
    @has_stats,
    @has_unique_constraint,
    @has_default_constraint,
    @has_check_constraint;
    
    WHILE (@@FETCH_STATUS = 0)
    BEGIN;
    
    /************************************************************************************************************************************
    *   Generates the code to update the colation for all affected columns in the table                                                 *
    ************************************************************************************************************************************/
    INSERT INTO #tempscriptstore (ScriptType,
                                  script)
    SELECT      'AlterCollation',
                N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' ALTER COLUMN '
                + QUOTENAME(c.name) + ' '
                + CASE WHEN ty.name = N'ntext' or ty.name = N'text'
                           THEN ty.name + N' COLLATE ' + @DatabaseCollation + ' '
                       ELSE ty.name + N'(' + CASE WHEN c.max_length = -1
                                                      THEN N'MAX'
                                                  ELSE CASE WHEN ty.name IN (N'nvarchar', N'nchar')
                                                                THEN CAST(c.max_length / 2 AS nvarchar(20))
                                                            ELSE CAST(c.max_length AS nvarchar(20))
                                                       END
                                             END + N') COLLATE ' + @DatabaseCollation
                  END + CASE WHEN c.is_nullable = 1 THEN N' NULL;' ELSE N' NOT NULL;' END
    FROM        sys.columns AS c
    INNER JOIN  sys.types   AS ty
       ON       ty.system_type_id = c.system_type_id
       AND      ty.name           <> N'sysname'
    WHERE       c.object_id = @object_id
    AND         c.collation_name    <> @DatabaseCollation;
    
    /************************************************************************************************************************************
    *   If the table has affected indexes, this creates the drop and recreate index scripts                                             *
    ************************************************************************************************************************************/
    IF @has_index > 0
    BEGIN;
        -- Process indexes on affected columns, one by one
        DECLARE CursorIndex CURSOR LOCAL FORWARD_ONLY READ_ONLY STATIC FOR
        SELECT  ix.index_id,
                ix.name,
                CASE WHEN ix.is_unique = 1 THEN N'UNIQUE ' ELSE N'' END,
                ix.type_desc,
                ix.filter_definition,
                CASE WHEN ix.is_padded = 1
                         THEN N'PAD_INDEX = ON, '
                     ELSE N'PAD_INDEX = OFF, '
                END + CASE WHEN ix.allow_page_locks = 1
                               THEN N'ALLOW_PAGE_LOCKS = ON, '
                           ELSE N'ALLOW_PAGE_LOCKS = OFF, '
                      END + CASE WHEN ix.allow_row_locks = 1
                                     THEN N'ALLOW_ROW_LOCKS = ON, '
                                 ELSE N'ALLOW_ROW_LOCKS = OFF, '
                            END + CASE WHEN INDEXPROPERTY(ix.object_id, ix.name, 'IsStatistics') = 1
                                           THEN N'STATISTICS_NORECOMPUTE = ON, '
                                       ELSE N'STATISTICS_NORECOMPUTE = OFF, '
                                  END + CASE WHEN ix.ignore_dup_key = 1
                                                 THEN N'IGNORE_DUP_KEY = ON, '
                                             ELSE N'IGNORE_DUP_KEY = OFF, '
                                        END + N'SORT_IN_TEMPDB = OFF, FILLFACTOR ='
                + CASE WHEN ix.fill_factor = 0
                           THEN CAST(100 AS nvarchar(3))
                       ELSE CAST(ix.fill_factor AS nvarchar(3))
                  END                            AS IndexOptions,
                ix.is_disabled,
                FILEGROUP_NAME(ix.data_space_id) AS FileGroupName
        FROM    sys.indexes AS ix
        WHERE   ix.object_id        = @object_id
        AND     ix.type                 <> 0 -- Exclude heaps
        AND     ix.is_primary_key       = 0 -- Exclude primary key constraints (handled separately)
        AND     ix.is_unique_constraint = 0 -- Exclude unique constraints (handled separately)
        AND     EXISTS (SELECT      *   -- Has to constrain at least one column with wrong collation
                        FROM        sys.index_columns AS ic
                        INNER JOIN  sys.columns       AS c
                           ON       c.object_id       = ic.object_id
                           AND      c.column_id       = ic.column_id
                           AND      c.collation_name  <> @DatabaseCollation
                        INNER JOIN  sys.types         AS ty
                           ON       ty.system_type_id = c.system_type_id
                           AND      ty.name           <> N'sysname'
                        WHERE       ic.index_id = ix.index_id
                        AND         ic.object_id        = ix.object_id);
    
        OPEN CursorIndex;
        FETCH NEXT FROM CursorIndex
        INTO @index_id,
             @IndexName,
             @is_unique,
             @IndexTypeDesc,
             @filter_definition,
             @IndexOptions,
             @is_disabled,
             @FileGroupName;
    
        WHILE (@@FETCH_STATUS = 0)
        BEGIN;
            -- For each index, use a nested cursor to build lists of indexed and inclued columns
            SET @IndexColumns = N'';
            SET @IncludedColumns = N'';
    
            DECLARE CursorIndexColumn CURSOR FOR
            SELECT      c.name,
                        ic.is_descending_key,
                        ic.is_included_column
            FROM        sys.index_columns AS ic
            INNER JOIN  sys.columns       AS c
               ON       c.object_id = ic.object_id
               AND      c.column_id = ic.column_id
            WHERE       ic.object_id = @object_id
            AND         ic.index_id          = @index_id
            ORDER BY    ic.index_column_id;
    
            OPEN CursorIndexColumn;
            FETCH NEXT FROM CursorIndexColumn
            INTO @ColumnName,
                 @IsDescendingKey,
                 @IsIncludedColumn;
    
            WHILE (@@FETCH_STATUS = 0)
            BEGIN;
                IF @IsIncludedColumn = 0
                    SET @IndexColumns += QUOTENAME(@ColumnName)
                                         + CASE WHEN @IsDescendingKey = 1 THEN N' DESC, ' ELSE N' ASC, ' END;
                ELSE
                    SET @IncludedColumns += QUOTENAME(@ColumnName) + N', ';
    
                FETCH NEXT FROM CursorIndexColumn
                INTO @ColumnName,
                     @IsDescendingKey,
                     @IsIncludedColumn;
            END;
    
            CLOSE CursorIndexColumn;
            DEALLOCATE CursorIndexColumn;
    
            -- Remove trailing comma
            SET @IndexColumns = SUBSTRING(@IndexColumns, 1, LEN(@IndexColumns) - 1);
            IF @IncludedColumns <> N''
                SET @IncludedColumns = SUBSTRING(@IncludedColumns, 1, LEN(@IncludedColumns) - 1);
    
            -- Generate DROP INDEX statement
            INSERT INTO #tempscriptstore (ScriptType,
                                          script)
            SELECT  'DropIndex',
                    N'DROP INDEX ' + QUOTENAME(@SchemaName) + '.' + QUOTENAME(@TableName) + '.' + QUOTENAME(@IndexName)
                    + N';';
    
            -- Generate CREATE INDEX statement
            INSERT INTO #tempscriptstore (ScriptType,
                                          script)
            SELECT  'CreateIndex',
                    N'CREATE ' + @is_unique + @IndexTypeDesc + N' INDEX ' + QUOTENAME(@IndexName) + N' ON '
                    + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N'(' + @IndexColumns + N') '
                    + CASE WHEN @IncludedColumns <> N''
                               THEN N'INCLUDE (' + @IncludedColumns + N')'
                           ELSE N''
                      END 
                    + CASE WHEN @filter_definition <> '' 
                                THEN N' WHERE ' + @filter_definition ELSE '' 
                      END 
                    + N' WITH (' + @IndexOptions + N') ON ' + QUOTENAME(@FileGroupName) + N';';
            -- Generate script to (re)disable disabled index after creating it
            IF @is_disabled = 1
                INSERT INTO #tempscriptstore (ScriptType,
                                              script)
                SELECT  'DisableIndex',
                        N'ALTER INDEX ' + QUOTENAME(@IndexName) + N' ON ' + QUOTENAME(@SchemaName) + N'.'
                        + QUOTENAME(@TableName) + N' DISABLE;';
    
            FETCH NEXT FROM CursorIndex
            INTO @index_id,
                 @IndexName,
                 @is_unique,
                 @IndexTypeDesc,
                 @filter_definition,
                 @IndexOptions,
                 @is_disabled,
                 @FileGroupName;
        END;
    
        CLOSE CursorIndex;
        DEALLOCATE CursorIndex;
    END;
    
    /************************************************************************************************************************************
    *   If the table has an affected 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 @has_key_constraint > 0
    BEGIN;
        -- Find columns and other metadata for primary key
        SELECT      kc.object_id                                                                          AS constid,
                    kc.name                                                                               AS constraint_name,   -- PK name
                    QUOTENAME(c.name) + CASE WHEN ic.is_descending_key = 1 THEN N' DESC' ELSE N' ASC' END AS pk_col,
                    ic.key_ordinal,
                    i.name                                                                                AS index_name,
                    i.type_desc                                                                           AS index_type,
                    QUOTENAME(fg.name)                                                                    AS filegroup_name,
                    N' WITH (PAD_INDEX = ' + CASE WHEN i.is_padded = 0 THEN N'OFF' ELSE N'ON' END + N', IGNORE_DUP_KEY = '
                    + CASE WHEN i.ignore_dup_key = 0 THEN N'OFF' ELSE N'ON' END + N', ALLOW_ROW_LOCKS = '
                    + CASE WHEN i.allow_row_locks = 0 THEN N'OFF' ELSE N'ON' END + ', ALLOW_PAGE_LOCKS = '
                    + CASE WHEN i.allow_page_locks = 0 THEN N'OFF)' ELSE N'ON)' END                       AS index_property
        INTO        #temp_pk
        FROM        sys.key_constraints AS kc
        INNER JOIN  sys.indexes         AS i
           ON       i.object_id      = kc.parent_object_id
           AND      i.is_primary_key = 1
        INNER JOIN  sys.index_columns   AS ic
           ON       ic.object_id     = i.object_id
           AND      ic.index_id      = i.index_id
        INNER JOIN  sys.columns         AS c
           ON       c.object_id      = ic.object_id
           AND      c.column_id      = ic.column_id
        INNER JOIN  sys.filegroups      AS fg
           ON       fg.data_space_id = i.data_space_id
        WHERE       kc.type     = 'PK'
        AND         kc.parent_object_id = @object_id;
    
        -- Generate DROP CONSTRAINT statement
        INSERT INTO #tempscriptstore (ScriptType,
                                      script)
        SELECT  TOP (1) -- One DROP statement, even if there are multiple columns
                'DropPrimaryKey',
                N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' DROP CONSTRAINT '
                + QUOTENAME(constraint_name) + N';'
        FROM    #temp_pk;
    
        -- Generate CREATE CONSTRAINT statement
        INSERT INTO #tempscriptstore (ScriptType,
                                      script)
        SELECT  TOP (1) -- One CREATE statement, even if there are multiple columns
                'AddPrimaryKey',
                N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' ADD CONSTRAINT '
                + QUOTENAME(p.constraint_name) + N' PRIMARY KEY ' + CAST(p.index_type AS nvarchar(100)) + N' ('
                + STUFF((SELECT     N', ' + pk_col  -- This generates a comma-separated list of the columns, in order
                         FROM       #temp_pk
                         ORDER BY   key_ordinal
                        FOR XML PATH('')),
                        1,
                        2,
                        N'') + N')' + p.index_property + N' ON ' + p.filegroup_name + N';'
        FROM    #temp_pk AS p;
    
        DROP TABLE #temp_pk;
    END;

Часть вторая

Примечание. Это не мое решение, это комментарии к компиляции, которые сработали для меня по этому URL-адресу https://sqlserverfast.com/blog/hugo/2019/01/collation-change-script/.

          /************************************************************************************************************************************
    *   If the table has a foreign key constraint on an affected column, this creates the drop and recreate constraint script           *
    *   this has been taken and adapted from a script found online cretaed by Jayakumaur R                                              *
    ************************************************************************************************************************************/
    IF @has_foreign_key > 0
    BEGIN;
        -- Process foreign key constraints on affected columns, one by one
        DECLARE foreignkeycursor CURSOR FOR
        SELECT  fk.object_id,
                fk.name
        FROM    sys.foreign_keys AS fk
        WHERE   fk.parent_object_id = @object_id
        AND     EXISTS (SELECT      *   -- Has to constrain at least one column with wrong collation
                        FROM        sys.foreign_key_columns AS fkc
                        INNER JOIN  sys.columns             AS c
                           ON       c.object_id       = fkc.parent_object_id
                           AND      c.column_id       = fkc.parent_column_id
                           AND      c.collation_name  <> @DatabaseCollation
                        INNER JOIN  sys.types               AS ty
                           ON       ty.system_type_id = c.system_type_id
                           AND      ty.name           <> N'sysname'
                        WHERE       fkc.parent_object_id = fk.parent_object_id
                        AND         fkc.constraint_object_id     = fk.object_id);
    
        OPEN foreignkeycursor;
        FETCH NEXT FROM foreignkeycursor
        INTO @FK_objectid,
             @FK_name;
    
        WHILE (@@FETCH_STATUS = 0)
        BEGIN;
            -- Find columns and other metadata for foreign key
            SELECT      fk.object_id                                      AS constid,
                        fk.name                                           AS constraint_name,   -- FK name
                        fkc.constraint_column_id                          AS column_ordinal,
                        QUOTENAME(c1.name)                                AS key_col,
                        QUOTENAME(OBJECT_SCHEMA_NAME(fk.referenced_object_id)) + N'.'
                        + QUOTENAME(OBJECT_NAME(fk.referenced_object_id)) AS ref_table,
                        QUOTENAME(c2.name)                                AS ref_col,
                        CASE WHEN fk.delete_referential_action <> 0 -- No action
                                 THEN N' ON DELETE ' + fk.delete_referential_action_desc
                             ELSE N''
                        END                                               AS delete_cascade,
                        CASE WHEN fk.update_referential_action <> 0 -- No action
                                 THEN N' ON UPDATE ' + fk.update_referential_action_desc
                             ELSE N''
                        END                                               AS update_cascade,
                        fk.is_not_trusted,
                        fk.is_disabled
            INTO        #temp_fk
            FROM        sys.foreign_keys        AS fk
            INNER JOIN  sys.foreign_key_columns AS fkc
               ON       fkc.parent_object_id     = fk.parent_object_id
               AND      fkc.constraint_object_id = fk.object_id
            INNER JOIN  sys.columns             AS c1
               ON       c1.object_id             = fkc.parent_object_id
               AND      c1.column_id             = fkc.parent_column_id
            INNER JOIN  sys.columns             AS c2
               ON       c2.object_id             = fkc.referenced_object_id
               AND      c2.column_id             = fkc.referenced_column_id
            WHERE       fk.object_id = @FK_objectid;
    
            -- Generate DROP CONSTRAINT statement
            INSERT INTO #tempscriptstore (ScriptType,
                                          script)
            SELECT  'DropForeignKey',
                    N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' DROP CONSTRAINT '
                    + QUOTENAME(@FK_name) + N';';
    
            -- Generate CREATE CONSTRAINT statement (always as ënabled, "not trusted"; status is changed later in script)
            INSERT INTO #tempscriptstore (ScriptType,
                                          script)
            SELECT  TOP (1) -- One CREATE statement, even if there are multiple columns
                    'AddForeignKey',
                    N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName)
                    + N' WITH NOCHECK ADD CONSTRAINT ' + QUOTENAME(constraint_name) + N' FOREIGN KEY ('
                    + STUFF(
                      (SELECT       N', ' + key_col -- This generates a comma-separated list of the constrained columns, in order
                       FROM         #temp_fk
                       ORDER BY     column_ordinal
                      FOR XML PATH('')),
                      1,
                      2,
                      N'') + N') REFERENCES ' + ref_table + N'('
                    + STUFF(
                      (SELECT       N', ' + ref_col -- This generates a comma-separated list of the referencedcolumns, in order
                       FROM         #temp_fk
                       ORDER BY     column_ordinal
                      FOR XML PATH('')),
                      1,
                      2,
                      N'') + N')' + delete_cascade + update_cascade + ';'
            FROM    #temp_fk;
    
            -- If constraint was disabled, add code to disable it again
            INSERT INTO #tempscriptstore (ScriptType,
                                          script)
            SELECT  TOP (1) -- One CREATE statement, even if there are multiple columns
                    'DisableForeignKey',
                    N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' NOCHECK CONSTRAINT '
                    + QUOTENAME(constraint_name) + N';'
            FROM    #temp_fk
            WHERE   is_disabled = 1;
    
            -- If constraint was trusted, add code to force re-check so it's trudsted again
            INSERT INTO #tempscriptstore (ScriptType,
                                          script)
            SELECT  TOP (1) -- One CREATE statement, even if there are multiple columns
                    'CheckForeignKey',
                    N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName)
                    + N' WITH CHECK CHECK CONSTRAINT ' + QUOTENAME(constraint_name) + N';'
            FROM    #temp_fk
            WHERE   is_not_trusted = 0;
    
            DROP TABLE #temp_fk;
    
            FETCH NEXT FROM foreignkeycursor
            INTO @FK_objectid,
                 @FK_name;
        END;
        CLOSE foreignkeycursor;
        DEALLOCATE foreignkeycursor;
    END;
    
    /*comment code 
    -- DROP and CREATE statistics for manual statistics has been disabled for now
    /************************************************************************************************************************************
    * If the column has statistics that aren't part of an index this creates the drop and recreate scripts *
    ************************************************************************************************************************************/
    IF @has_stats > 0
    AND @has_index = 0
    BEGIN
    DECLARE stats_cursor CURSOR FOR
    SELECT sc.stats_id
    FROM sys.stats_columns AS sc
    JOIN sys.stats AS s
    ON s.object_id = sc.object_id
    AND s.stats_id = sc.stats_id
    AND s.user_created = 1
    WHERE sc.object_id = @object_id
    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 AS s
    WHERE s.object_id = @object_id
    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 AS sc
            JOIN    sys.stats         AS s
              ON    s.stats_id  = sc.stats_id
              AND   s.object_id = sc.object_id
            JOIN    sys.columns       AS c
              ON    c.object_id = sc.object_id
              AND   c.column_id = sc.column_id
            WHERE   sc.object_id = @object_id
            AND     sc.stats_id      = @stats_id;
            WITH
            cte AS
                (SELECT DISTINCT ts.st_table,
                                 ts.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 AS 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 table has unique constraints on affected columns, this creates the drop and recreate scripts                             *
    ************************************************************************************************************************************/
    
    IF @has_unique_constraint > 0
    BEGIN;
        -- Process unique constraints on affected columns, one by one
        DECLARE uniquecursor CURSOR FOR
        SELECT  kc.object_id,
                kc.name,
                kc.unique_index_id
        FROM    sys.key_constraints AS kc
        WHERE   kc.parent_object_id = @object_id
        AND     kc.type                 = 'UQ'
        AND     EXISTS (SELECT      *   -- Has to constrain at least one column with wrong collation
                        FROM        sys.index_columns AS ic
                        INNER JOIN  sys.columns       AS c
                           ON       c.object_id       = ic.object_id
                           AND      c.column_id       = ic.column_id
                           AND      c.collation_name  <> @DatabaseCollation
                        INNER JOIN  sys.types         AS ty
                           ON       ty.system_type_id = c.system_type_id
                           AND      ty.name           <> N'sysname'
                        WHERE       ic.object_id = kc.parent_object_id
                        AND         ic.index_id          = kc.unique_index_id);
    
        OPEN uniquecursor;
        FETCH NEXT FROM uniquecursor
        INTO @UQ_objectid,
             @UQ_name,
             @UQ_index_id;
    
        WHILE (@@FETCH_STATUS = 0)
        BEGIN;
            -- Find columns and other metadata for unique constraint
            SELECT      QUOTENAME(c.name) + CASE WHEN ic.is_descending_key = 1 THEN N' DESC' ELSE N' ASC' END     AS uq_col,
                        ic.key_ordinal,
                        i.name                                                                                    AS index_name,
                        i.type_desc                                                                               AS index_type,
                        QUOTENAME(fg.name)                                                                        AS filegroup_name,
                        N' WITH (PAD_INDEX = ' + CASE WHEN i.is_padded = 0 THEN N'OFF' ELSE N'ON' END
                        + N', IGNORE_DUP_KEY = ' + CASE WHEN i.ignore_dup_key = 0 THEN N'OFF' ELSE N'ON' END
                        + N', ALLOW_ROW_LOCKS = ' + CASE WHEN i.allow_row_locks = 0 THEN N'OFF' ELSE N'ON' END
                        + ', ALLOW_PAGE_LOCKS = ' + CASE WHEN i.allow_page_locks = 0 THEN N'OFF)' ELSE N'ON)' END AS index_property
            INTO        #temp_uq
            FROM        sys.indexes       AS i
            INNER JOIN  sys.index_columns AS ic
               ON       ic.object_id     = i.object_id
               AND      ic.index_id      = i.index_id
            INNER JOIN  sys.columns       AS c
               ON       c.object_id      = ic.object_id
               AND      c.column_id      = ic.column_id
            INNER JOIN  sys.filegroups    AS fg
               ON       fg.data_space_id = i.data_space_id
            WHERE       i.object_id    = @object_id
            AND         i.index_id             = @UQ_index_id
            AND         i.is_unique_constraint = 1;
    
            -- Generate DROP CONSTRAINT statement
            INSERT INTO #tempscriptstore (ScriptType,
                                          script)
            SELECT  'DropUniqueKey',
                    N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' DROP CONSTRAINT '
                    + QUOTENAME(@UQ_name) + N';';
    
            -- Generate CREATE CONSTRAINT statement
            INSERT INTO #tempscriptstore (ScriptType,
                                          script)
            SELECT  TOP (1) -- One CREATE statement, even if there are multiple columns
                    'AddUniqueKey',
                    N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' ADD CONSTRAINT '
                    + QUOTENAME(@UQ_name) + N' UNIQUE ' + CAST(index_type AS nvarchar(100)) + N' ('
                    + STUFF((SELECT     N', ' + uq_col  -- This generates a comma-separated list of the columns, in order
                             FROM       #temp_uq
                             ORDER BY   key_ordinal
                            FOR XML PATH('')),
                            1,
                            2,
                            N'') + N')' + index_property + N' ON ' + filegroup_name + N';'
            FROM    #temp_uq;
    
            DROP TABLE #temp_uq;
    
            FETCH NEXT FROM uniquecursor
            INTO @UQ_objectid,
                 @UQ_name,
                 @UQ_index_id;
        END;
        CLOSE uniquecursor;
        DEALLOCATE uniquecursor;
    END;
    
    
    /************************************************************************************************************************************
    *  If the table has default constraints on affected columns, this creates the drop and recreate scripts in the table                *
    ************************************************************************************************************************************/
    IF @has_default_constraint > 0
    BEGIN
        INSERT INTO #tempscriptstore (ScriptType,
                                      script)
        SELECT      'DropDefault',
                    N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' DROP CONSTRAINT '
                    + QUOTENAME(dc.name) + ' '
        FROM        sys.columns AS c 
        INNER JOIN  sys.default_constraints dc 
           ON       dc.object_id = c.default_object_id 
           AND      dc.parent_column_id = c.column_id 
        INNER JOIN  sys.types   AS ty
           ON       ty.system_type_id = c.system_type_id
           AND      ty.name           <> N'sysname'
        WHERE       c.object_id = @object_id
        AND         c.collation_name    <> @DatabaseCollation;
    
    
        INSERT INTO #tempscriptstore (ScriptType,
                                      script)
        SELECT      'CreateDefault',
                    N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' ADD DEFAULT '
                    + dc.definition + ' FOR ' + QUOTENAME(c.name) 
        FROM        sys.columns AS c 
        INNER JOIN  sys.default_constraints dc on dc.object_id = c.default_object_id 
        INNER JOIN  sys.types   AS ty
           ON       ty.system_type_id = c.system_type_id
           AND      ty.name           <> N'sysname'
        WHERE       c.object_id = @object_id
        AND         c.collation_name    <> @DatabaseCollation;
    End
    
    /************************************************************************************************************************************
    * If the table has check constraints on affected columns, this creates the drop and recreate scripts in the table *
    ************************************************************************************************************************************/
    IF @has_check_constraint > 0
    BEGIN
        INSERT INTO #tempscriptstore (ScriptType,
                                        script)
        SELECT 'DropCheck',
        N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' DROP CONSTRAINT '
        + QUOTENAME(cc.name) + ' '
        FROM sys.columns AS c
        INNER JOIN sys.check_constraints cc
        ON c.object_id = cc.parent_object_id
        AND cc.parent_column_id = c.column_id
        INNER JOIN sys.types AS ty
        ON ty.system_type_id = c.system_type_id
        AND ty.name <> N'sysname'
        WHERE c.object_id = @object_id
        AND c.collation_name <> @DatabaseCollation;
    
        INSERT INTO #tempscriptstore (ScriptType,
                                      script)
        SELECT      'CreateCheck',
                    N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' WITH CHECK ADD CONSTRAINT '
                    + QUOTENAME(cc.name) + ' CHECK ' + cc.definition 
        FROM        sys.columns AS c 
        INNER JOIN  sys.check_constraints cc 
            ON      cc.parent_object_id = c.object_id
            AND     cc.parent_column_id = c.column_id
        INNER JOIN  sys.types   AS ty
           ON       ty.system_type_id = c.system_type_id
           AND      ty.name           <> N'sysname'
        WHERE       c.object_id = @object_id
        AND         c.collation_name    <> @DatabaseCollation
        group by    cc.name, cc.definition;
    end
    
    
    FETCH NEXT FROM collationfix
    INTO @object_id,
         @SchemaName,
         @TableName,
         @has_key_constraint,
         @has_index,
         @has_foreign_key,
         @has_stats,
         @has_unique_constraint,
         @has_default_constraint,
         @has_check_constraint;
    END;
    CLOSE collationfix;
    DEALLOCATE collationfix;
    
    /************************************************************************************************************************************
    * Returns all the created scripts in the correct order for running *
    * Also add GO in between some sections so the entire script can execute at once *
    ************************************************************************************************************************************/
    DECLARE @oddnum INT = 1;
    WITH ScriptInput
    AS (SELECT script,
    CASE WHEN ScriptType = 'DropDefault'
    THEN 1
    WHEN ScriptType = 'DropForeignKey'
    THEN 3
    WHEN ScriptType = 'DropIndex'
    THEN 5
    WHEN ScriptType = 'DropUniqueKey'
    THEN 7
    WHEN ScriptType = 'DropPrimaryKey'
    THEN 9
    WHEN ScriptType = 'DropStatistics'
    THEN 11
    WHEN ScriptType = 'DropCheck'
    THEN 13
    WHEN ScriptType = 'AlterCollation'
    THEN 15
    WHEN ScriptType = 'AddPrimaryKey'
    THEN 17
    WHEN ScriptType = 'AddUniqueKey'
    THEN 19
    WHEN ScriptType = 'CreateIndex'
    THEN 21
    WHEN ScriptType = 'AddStatistics'
    THEN 23
    WHEN ScriptType = 'AddForeignKey'
    THEN 25
    WHEN ScriptType = 'DisableForeignKey'
    THEN 27
    WHEN ScriptType = 'CheckForeignKey'
    THEN 29
    WHEN ScriptType = 'DisableIndex'
    THEN 31
    WHEN ScriptType = 'CreateDefault'
    THEN 33
    WHEN ScriptType = 'CreateCheck'
    THEN 35
    ELSE 99
    END AS SortOrder
    
    FROM #tempscriptstore
    UNION ALL
    SELECT CASE WHEN n.num > 0
    THEN 'GO' + CHAR(13)+CHAR(10) + descrip
    ELSE descrip end,
    n.num
    FROM (VALUES (0, '--- Drop Default'),
    (2, '--- Drop Foreign Key'),
    (4, '--- Drop Index'),
    (6, '--- Drop Unique Key'),
    (8, '--- Drop Primary Key'),
    --(10, '--- Drop Statistics'),
    (12, '--- Drop Check '),
    (14, '--- Alter Collation '),
    (16, '--- Add Primary Key '),
    (18, '--- Add Unique Key '),
    (20, '--- Create Index '),
    --(22, '--- Add Statistics '),
    (24, '--- Add Foreign Key '),
    (26, '--- Disable Foreign Key '),
    (28, '--- Check Foreign Key '),
    (30, '--- Disable Index '),
    (32, '--- Create Default '),
    (34, '--- Create Check '),
    (36, '--- End of script')
    ) AS n (num, descrip) )
    SELECT ScriptInput.script
    FROM ScriptInput
    ORDER BY ScriptInput.SortOrder;
    
    DROP TABLE #tempscriptstore;

Возможно, проще использовать PowerShell и SMO, например:

      $db = Get-DbaDatabase -SqlInstance MyServer -Database MyDb
$db.Tables  | % { 
  $t = $_
  $t | % {
    If ($_.Collation -eq 'SQL_Latin1_General_CP1_CI_AS') {
      $_.Collation = 'Latin1_General_CI_AS'
    }
  }
}
Другие вопросы по тегам