0

Bugün bir arkadaşımın isteği üzerine yazdığım stored procedure’ü paylaşmak istiyorum.

Belirttiğiniz Database içerisindeki ister spesific table’ın, ister bütün table’ların column collation’larını değiştirmenize yarayan bir SP’yi paylaşıyorum. Örneğin yazılım departmanından bir developer sizden TestDB database’indeki bütün table’lardaki column collation yapısı “Turkish_CI_AS” olanları “Latin1_General_CI_AS” olarak değiştirmenizi isteyebilir.

Bu tarz isteklerin herzaman ufak boyutlu database’ler üzerinden gelmeyeceğine biliyoruz. Manuel olarak yapmak schema yapısı çok kapsamlı olan database’lerde çok can sıkıcı hal alabilir. Yazdığım bu SP’nin bu şekilde gelen case’lerde işinize yarayacağını düşünüyorum.
Yapmanız gereken değiştirilmesini istediğiniz collation yapısı ile değiştirilecek collation yapısını Database ismi ile belirtmektir. Output olarak alter scriptlerini listeleyecektir.
/*
EXEC [master].[dbo].[sp_ChangeColumnCollation]
     @Database = 'TestDB',
     @Table = 'TestTable', --Optional
     @CurrentCollation = 'Turkish_CI_AS',
     @NewCollation = 'Latin1_General_CI_AS'
*/

USE [master]
GO

CREATE PROC [dbo].[sp_ChangeColumnCollation]
            @Database          NVARCHAR(50),
            @Table             NVARCHAR(50) = NULL,
            @CurrentCollation  NVARCHAR(50),
            @NewCollation      NVARCHAR(50)
AS
SET NOCOUNT ON
DECLARE @ColumnName        NVARCHAR(50),
        @ColumnDataType    NVARCHAR(10),
        @ColumnDataLength  NVARCHAR(50),
        @IsNullable        NVARCHAR(10),
        @Collation         NVARCHAR(50),
        @SchemaName        NVARCHAR(50),
        @TableName         NVARCHAR(50),
        @SQL               NVARCHAR(MAX)

SET @SQL = 
    'SELECT
                a.[name]      AS [Table]
               ,e.[name]      AS [Schema]
               ,b.[name]      AS [Column]
               ,b.[collation] AS [Collation]
               ,c.[name]      AS [ColumnDataType]
               ,b.[prec]      AS [ColumnDataLength]
               , CASE WHEN b.isnullable = 1 THEN ''NULL''
                      WHEN b.isnullable = 0 THEN ''NOT NULL''
                 END          AS [IsNullable]
             FROM ' + @Database + 
    '.sys.sysobjects a
               INNER JOIN  ' + @Database + 
    '.sys.syscolumns b
                       ON a.[Id] = b.[Id]
               INNER JOIN  ' + @Database + 
    '.sys.systypes c
                       ON c.[xtype] = b.[xtype]
               INNER JOIN  ' + @Database + 
    '.sys.tables d
                       ON a.[id] = d.[object_id]
               INNER JOIN  ' + @Database + 
    '.sys.schemas e
                       ON d.[schema_id] = e.[schema_id]
             WHERE a.[type] = ''U''
               AND b.[collation] = ''' + @CurrentCollation + ''''

IF @Table IS NOT NULL
BEGIN
    SET @SQL = @SQL + ' AND a.[Name] = ''' + @Table + ''''
END          

DECLARE @CollationCursor CURSOR 

SET @SQL = 'SET @CollationCursor = CURSOR FORWARD_ONLY STATIC FOR '
    + @SQL + ' ; OPEN @CollationCursor'

EXEC sp_executesql @SQL,
     N'@CollationCursor CURSOR OUTPUT',
     @CollationCursor OUTPUT   

            FETCH NEXT FROM @CollationCursor INTO @TableName,
                                                  @SchemaName,
                                                  @ColumnName,
                                                  @Collation,
                                                  @ColumnDataType,
                                                  @ColumnDataLength,
                                                  @IsNullable

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT 'ALTER TABLE ' + @Database + '.'
    + @SchemaName + '.'
    + @TableName + ' ALTER COLUMN '
    + @ColumnName + ' '
    + @ColumnDataType + '('
    + @ColumnDataLength + ') COLLATE '
    + @NewCollation + ' ' + @IsNullable

    FETCH NEXT FROM @CollationCursor INTO @TableName,
    @SchemaName,
    @ColumnName,
    @Collation,
    @ColumnDataType,
    @ColumnDataLength,
    @IsNullable
END

    CLOSE @CollationCursor
    DEALLOCATE @CollationCursor
GO

 

Leave a Reply