Update Collation of all fields in database on the fly

后端 未结 8 1703
说谎
说谎 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:19

    Further to Owais Iqbal's answer rewritten the code by edosoft and put it in a loop to execute the actual T-SQL statements, you can grab the default collation from the database

    -- **************** BEGIN INPUT **********************
    USE [YourDBName]
    -- **************** END INPUT ************************
    
    -- **************** BEGIN GET DB COLLATION ***********
    DECLARE @collation NVARCHAR(128)
    SELECT @collation = collation_name
    FROM sys.databases WHERE database_id = DB_ID()
    
    PRINT 'Default database collation: ' + @collation
    PRINT ''
    -- **************** END GET DB COLLATION *************
    
    -- **************** BEGIN LOGIC **********************
    
    0 讨论(0)
  • 2020-12-07 21:26

    One option is to use a program like Red Gate SQL Compare (I'm sure there's others too). With it you can generate script files for your schema with collation included (make sure to turn that on in the options), then do a search/replace in the files updating it to the new collation, then re-compare them back to your actual database.

    At this point SQL Compare will be able to apply those changes (or save the changes to a script file if you prefer), and your existing columns are all fixed.

    In theory you could do all of this while still under the trial period, though I would suggest it's a good tool to keep around as it makes many SQL tasks easier!

    0 讨论(0)
  • 2020-12-07 21:29

    To fix this problem, you need far more fire power then this script provides. I tried the script and ran into problems with dependent objects that couldn't update: indexes, keys and procedures. The final solution took just 5 minutes with this code project app. The app says it is for Sql Server 2000 but I used it successfully with 2008.

    http://www.codeproject.com/Articles/12753/SQL-Server-2000-Collation-Changer

    I can't stress this enough. BACKUP YOUR DATABASE. I had to use my backup three times to complete this task.

    0 讨论(0)
  • 2020-12-07 21:31

    The code fails to take NText, NChar and NVarchar double bytes into account. If you have NText it will fail with Ntext(16) unable to set size on NText.

    For NChar and NVarChar it doubles the length, because it fails to divide size by 2.

    Another Quirky little detail, is that for Nvarchar at least, -1 is not MAX, but 0 is.

    This is a very very ugly hack on the code, just to illustrate the issues:

    ALTER TABLE [BlanketBruger] ALTER COLUMN [BrugerNavn] nvarchar(50)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [BlanketBruger] ALTER COLUMN [BrugerFuldNavn] nvarchar(255)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [blanketgruppe] ALTER COLUMN [GruppeNavn] nvarchar(255)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [blanketSerie] ALTER COLUMN [SerieTitel] nvarchar(255)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [blanketSerie] ALTER COLUMN [SerieAlias] nvarchar(255)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [FormUse] ALTER COLUMN [HostName] nvarchar(50)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [BackendLog] ALTER COLUMN [value1] nvarchar(1000)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [BackendLog] ALTER COLUMN [value2] nvarchar(1000)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [BackendLog] ALTER COLUMN [ip] varchar(20)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [BackendLog] ALTER COLUMN [username] nvarchar(100)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [BackendLog] ALTER COLUMN [gruppenavn] nvarchar(100)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [BackendLog] ALTER COLUMN [scriptname] nvarchar(100)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [BackendLog] ALTER COLUMN [querystring] nvarchar(1000)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [BackendLog] ALTER COLUMN [useragent] nvarchar(400)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [BackendLog] ALTER COLUMN [sessionid] varchar(50)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [BackendLog] ALTER COLUMN [htmlcontent] nvarchar(MAX)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [frontendlog] ALTER COLUMN [value1] nvarchar(1000)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [frontendlog] ALTER COLUMN [value2] nvarchar(1000)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [frontendlog] ALTER COLUMN [ip] nvarchar(50)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [frontendlog] ALTER COLUMN [querystring] nvarchar(1000)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [frontendlog] ALTER COLUMN [useragent] nvarchar(400)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [frontendlog] ALTER COLUMN [sessionid] nvarchar(50)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [log4net] ALTER COLUMN [Thread] varchar(255)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [log4net] ALTER COLUMN [Level] varchar(50)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [log4net] ALTER COLUMN [Logger] varchar(255)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [log4net] ALTER COLUMN [Message] text   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [log4net] ALTER COLUMN [Exception] varchar(MAX)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [log4net] ALTER COLUMN [Server] varchar(255)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [OioSamlLog] ALTER COLUMN [Server] varchar(255)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [OioSamlLog] ALTER COLUMN [Thread] varchar(255)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [OioSamlLog] ALTER COLUMN [Level] varchar(50)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [OioSamlLog] ALTER COLUMN [Message] varchar(MAX)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [BlanketSubmitTemp] ALTER COLUMN [FileContentIdentifier] nvarchar(50)   COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    ALTER TABLE [BlanketSubmitTemp] ALTER COLUMN [FileContent] ntext   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    ALTER TABLE [BlanketSubmitTemp] ALTER COLUMN [FileName] nvarchar(255)   COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    
    0 讨论(0)
  • 2020-12-07 21:35

    How about:

    DECLARE @collation NVARCHAR(64)
    SET @collation = 'Latin1_General_CI_AS'
    
    SELECT
        'ALTER TABLE [' + TABLE_SCHEMA  + '].[' + TABLE_NAME + '] '
      + 'ALTER COLUMN [' + COLUMN_NAME + '] '
      + DATA_TYPE + '(' + CASE CHARACTER_MAXIMUM_LENGTH 
            WHEN -1 THEN 'MAX' 
            ELSE CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) END + ') '
      + 'COLLATE ' + @collation + ' '
      + CASE WHEN IS_NULLABLE = 'NO' THEN 'NOT NULL' ELSE 'NULL' END
    FROM INFORMATION_SCHEMA.columns
    WHERE  COLLATION_NAME IS NOT NULL
    AND COLLATION_NAME <> @collation
    
    0 讨论(0)
  • 2020-12-07 21:37

    You can change the collation of any new objects that are created in a user database by using the COLLATE clause of the ALTER DATABASE statement. This statement does not change the collation of the columns in any existing user-defined tables. These can be changed by using the COLLATE clause of ALTER TABLE.

    Reference: Setting and Changing the Database Collation

    If there are too many columns, you can loop through SYS.COLUMNS to apply the ALTER TABLE statement.

    0 讨论(0)
提交回复
热议问题