web-dev-qa-db-fra.com

comment changer l'assemblage à toutes les colonnes de la base de données?

Je voudrais changer le classement de toutes les colonnes de toutes les tables de ma base de données. Dans un autre poste en débordement de pile, j'ai trouvé ce script: ( post )

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

Cependant, lorsque je vois le classement des colonnes, je constate que le classement est l'ancien classement.

Le classement est AS, je peux donc avoir "ANIMAL" et "ÁNIMAL". Lorsque j'exécute le script, je n'ai aucune erreur. Je pense que j'aurais une erreur car le nouveau classement est AI. Cela me fait donc penser que le script ne fait rien.

Pourquoi est-ce que je peux changer le classement de toutes les colonnes de toutes mes tables dans la base de données?

Merci. 

34
Álvaro García

Essaye celui-là -

Requête:

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'

Sortie:

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

Je poste une modification dans la réponse ci-dessus, qui traite des longueurs de caractère et de varchar, car ma précédente modification semble rejetée.

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'
7
David

J'ai rassemblé le script ci-dessous à partir de différentes sources qui suppriment les dépendances, met à jour le classement, puis recrée les objets dépendants. Cela résout le problème de la mise à jour du classement des colonnes ayant des dépendances (index, contraintes de clé étrangère, etc.).

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

Merci à tous pour vos suggestions, cela m’aide beaucoup lors de la migration de ma base de données de SQL Server 2008 R2 à 2014

REMARQUE: Certaines requêtes ont un VARCHAR non valide (-), je l’ai remplacée par VARCHAR (MAX) et tout fonctionne correctement.

Étapes pour changer de classement:

  1. Exécuter la requête ci-dessus et obtenir la requête Alter table
  2. Supprimer tous les index des tables et fonctions de valeur table
  3. Exécuter la requête générée à l'étape 1
  4. Créez des index de tables et des fonctions à valeur de table.
2
wajahat kaleem

Bien qu'aucune des autres approches ne fonctionne pour moi, cet article de Douglas P. Castilho m'a fourni une solution complète. Je le partage au cas où cela aiderait quelqu'un.

  1. Créer des sauvegardes de toutes les bases de données.
  2. Arrêtez les services SQL Server sur le serveur.
  3. Ouvrez une invite de commande et accédez au répertoire Binn, par exemple 

C:\Programmes\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Binn

  1. Exécutez la commande ci-dessous pour appliquer un nouveau classement.

sqlservr -m -T4022 -T3659 -q "[Entrez le nom du classement]"

  1. Démarrez à nouveau le service SQL Server.

C'est tout.

2
Arda A.

Avant de commencer cette opération, veuillez d'abord lire cet article . https://www.mssqltips.com/sqlservertip/3221/how-to-change-the-collation-of-a-sql-server-column/

Après avoir lu l’article ci-dessus et s’assurer que vous avez supprimé les références ci-dessous de votre base de données.

  • Une colonne calculée 
  • Un index Statistiques de distribution, généré automatiquement ou par l’instruction CREATE STATISTICS. 
  • Une contrainte de CHECK 
  • Une contrainte de clé étrangère

Appuyez sur le script ci-dessous sur votre base de données après cela, n'oubliez pas de modifier également le classement des bases de données.

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
1
Recep Selli

Pour ceux qui recherchent cette solution et qui utilisent PHPMyAdmin, une option se trouve au bas de l'onglet "Opérations de base de données" (cliquez sur une base de données puis sur "Opérations" dans la barre d'outils supérieure); faites défiler jusqu'à la case de classement, sélectionnez-en un, cochez les deux cases (une apparaît lorsque la première est cochée):

  • Changer tous les classements des tables
  • Changer toutes les collations des colonnes des tables

Semble exécuter un script semblable à ceux affichés; la console affiche la dernière commande exécutée:

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