Update Collation of all fields in database on the fly

后端 未结 8 1704
说谎
说谎 2020-12-07 21:00

We recently moved our database from our SQL Server 2005 server to our SQL Server 2008 server. Everything moved over fine, however now we are finding that we are getting col

相关标签:
8条回答
  • 2020-12-07 21:41

    Just in case anyone looking at this is using SQL server 2008, i had to make a couple modifications:

    SELECT 'ALTER TABLE [' + sys.objects.name + '] ALTER COLUMN ['
    + sys.columns.name + '] ' + sys.types.name + 
        CASE sys.types.name
        WHEN 'text' THEN ' '
        ELSE
        '(' + RTRIM(CASE sys.columns.max_length
        WHEN -1 THEN 'MAX'
        ELSE CONVERT(CHAR,sys.columns.max_length)
        END) + ') ' 
        END
    
        + ' ' + ' COLLATE Latin1_General_BIN ' + CASE sys.columns.is_nullable WHEN 0 THEN 'NOT NULL' ELSE 'NULL' END
        FROM sys.columns , sys.objects , sys.types
        WHERE sys.columns.object_id = sys.objects.object_id
        AND sys.objects.TYPE = 'U'
        AND sys.types.system_type_id = sys.columns.system_type_id
        AND sys.columns.collation_name IS NOT NULL
        AND NOT ( sys.objects.NAME LIKE 'sys%' )
        AND NOT ( sys.types.name LIKE 'sys%' )
    
    0 讨论(0)
  • 2020-12-07 21:44

    Okay I have rewritten the code by edosoft and put it in a loop to execute the actual T-SQL statements.

    -- **************** BEGIN INPUT **********************
    USE [YourDBName]
    
    DECLARE @collation NVARCHAR(128)
    -- enter you collation name below
    SET @collation = N'Latin1_General_CI_AS'
    -- **************** END INPUT ************************
    
    -- **************** BEGIN LOGIC **********************
    DECLARE @sqlCode VARCHAR(2048)
    
    DECLARE myCursor CURSOR LOCAL FOR
        SELECT 'ALTER TABLE [' + sys.objects.name + '] 
            ALTER COLUMN ['+ sys.columns.name + '] ' + sys.types.name + 
            CASE sys.types.name
                WHEN 'text' THEN ' '
                WHEN 'ntext' THEN ' '
                ELSE '(' + RTRIM(
                    CASE
                        WHEN sys.columns.max_length = -1 THEN 'MAX'
                        WHEN sys.columns.max_length > 4000 THEN 'MAX'
                        ELSE CONVERT(CHAR,sys.columns.max_length)
                    END) + ')' 
            END
            + ' COLLATE ' + @collation + CASE sys.columns.is_nullable WHEN 0 THEN ' NOT NULL' ELSE ' NULL' END
            FROM sys.columns , sys.objects , sys.types
            WHERE sys.columns.object_id = sys.objects.object_id
                AND sys.objects.TYPE = 'U'
                AND sys.types.system_type_id = sys.columns.system_type_id
                AND sys.columns.collation_name IS NOT NULL
                AND sys.columns.collation_name <> @collation
                AND NOT ( sys.objects.NAME LIKE 'sys%' )
                AND NOT ( sys.types.name LIKE 'sys%' )
    
    OPEN myCursor
    FETCH NEXT FROM myCursor INTO @sqlCode
    
    WHILE @@FETCH_STATUS = 0 BEGIN
        PRINT 'Executing: ' + @sqlCode
        BEGIN TRY
            EXEC(@sqlCode);
            PRINT 'Done!' + CHAR(10)
        END TRY
        BEGIN CATCH
            PRINT 'Error: ' + ERROR_MESSAGE() + CHAR(10)
        END CATCH
        FETCH NEXT FROM myCursor INTO @sqlCode
    END
    
    PRINT 'Finished!'
    -- **************** END LOGIC **********************
    

    If you get the error something similar to "Cannot create a row of size 8075 which is greater than the allowable maximum row size of 8060". Rebuild the table for which you are getting the error and run the above script again.

    ALTER TABLE [dbo].[YourTableName] REBUILD 
    
    0 讨论(0)
提交回复
热议问题