How to change collation of all database objects in SQL Server. Have you encountered a problem where you wanted to change your database collation to default or even just change it to a different type? I guess what you had initially done (like me) was to change the collation of the database. Well, that does not quite work well as the existing columns will not be changed and retain its current collation type, only the newly created objects will use this new collation type. So you are left to the option of changing the columns one at a time by going to the column property and restoring it to default, or choosing the collation type you want.

Well, that’s great if you need to change 10 columns or less but what if you want to change the whole database? What if it’s a primary key or a foreign key? Well, isn’t that a nightmare? Well, I will give you an easy solution and all you need to do is to run 6 easy steps. If you don’t want to recreate the database and pump data by using DTS or SSIS, then this is the solution for you; just make sure to backup and restore everything before doing any changes.

Step 1: Prepare your DB and change the collation to your desired one

Like I had said, backup your database as a part of the preparation. Once that’s done, change your collation to the desired type by going to the database properties by right clicking on the database and choosing properties. Once you are on the Properties window, choose options and you can see the collation from there, choose what you want, then hit OK. This will ensure that new objects created will be using the new collation.

Step 2: Create you Change Collation Script.

Next is to create a script to change the collation of every object in your database. You need to use information_schema to extract columns needed to be changed and from there we run a loop on all objects creating alter scripts on each item. Since it is a collation change, we will only need fields that uses character types and text types. What you need is to have a lot of commands similar to this.

ALTER TABLE TABLENAME ALTER COLUMN COLUMNNAME varchar(100) COLLATE Latin1_General_CI_AS NULL

So here is the code to generate that:

OPEN MyTableCursor
FETCH NEXT FROM MyTableCursor INTO @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE MyColumnCursor Cursor
FOR
SELECT COLUMN_NAME,DATA_TYPE, CHARACTER_MAXIMUM_LENGTH,
IS_NULLABLE from information_schema.columns
WHERE table_name = @TableName AND (Data_Type LIKE '%char%'
OR Data_Type LIKE '%text%') AND COLLATION_NAME <> @CollationName
ORDER BY ordinal_position
Open MyColumnCursor
FETCH NEXT FROM MyColumnCursor INTO @ColumnName, @DataType,
@CharacterMaxLen, @IsNullable
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SQLText = 'ALTER TABLE ' + @TableName + ' ALTER COLUMN [' + @ColumnName + '] ' +
@DataType + '(' + CASE WHEN @CharacterMaxLen = -1 THEN 'MAX' ELSE @CharacterMaxLen END +
') COLLATE ' + @CollationName + ' ' +
CASE WHEN @IsNullable = 'NO' THEN 'NOT NULL' ELSE 'NULL' END
PRINT @SQLText
FETCH NEXT FROM MyColumnCursor INTO @ColumnName, @DataType,
@CharacterMaxLen, @IsNullable
END
CLOSE MyColumnCursor
DEALLOCATE MyColumnCursor
FETCH NEXT FROM MyTableCursor INTO @TableName
END
CLOSE MyTableCursor
DEALLOCATE MyTableCursor

Run it then save the script for later use. Let us call the script “ChangeCollation.sql”. If you don’t have relationships, primary keys, and foreign keys then you don’t need to do the next step.

Step 3: Create a Stored Procedure to Script Indexes and Relationships

Well, if you have relationships, primary keys, and foreign keys, then that’s a good practice but you need to script them as you need to drop those before changing the collation. Initially, I thought I can do this with the wizard and choose to script indexes but it does not create on its own the table creation is always included so with a little help from Google, I don’t have to write a single piece of code. I found this really good script to do it and I got it from here: http://sqlblog.com/blogs/adammachanic/archive/2010/04/04/rejuvinated-script-creates-and-drops-for-candidate-keys-and-referencing-foreign-keys.aspx. I only separated the Create Indexes and Drop Indexes as we need to run a process in the middle. Here is the Create Index script, courtesy of Adam Machanic: /* Script Table Keys (C) 2010 Adam Machanic - amachanic@gmail.com http://sqlblog.com/blogs/adammachanic/archive/2010/04/04/ rejuvinated-script-creates-and-drops-for-candidate-keys -and-referencing-foreign-keys.aspx This script produces a script of all of the candidate keys (primary keys or unique constraints) as well as referencing foreign keys, for the target table. To use, put SSMS into "results in text" mode and run the script. The output will be a formatted script that you can cut and paste to use elsewhere. Don't forget to configure the maximum text size before using. The default is 256 characters--not enough for many cases.

Tools->Options->Query Results->Results to Text->Maximum number of characters->8192

    */
CREATE PROC [dbo].[ScriptCreateTableKeys]
@table_name SYSNAME
AS
BEGIN
SET NOCOUNT ON--Note: Disabled keys and constraints are ignored --TODO: Drop and re-create referencing XML indexes, FTS catalogs DECLARE @crlf CHAR(2)
SET @crlf = CHAR(13) + CHAR(10)
DECLARE @version CHAR(4)
SET @version = SUBSTRING(@@VERSION, LEN('Microsoft SQL Server') + 2, 4)
DECLARE @object_id INT
SET @object_id = OBJECT_ID(@table_name)
DECLARE @sql NVARCHAR(MAX)
IF @version NOT IN ('2005', '2008')
BEGIN
RAISERROR('This script only supports SQL Server 2005 and 2008', 16, 1)
RETURN
END
SET @sql = '' +
'SELECT ' +
'CASE ' +
'WHEN 1 IN (i.is_primary_key, i.is_unique_constraint) THEN ' +
'''ALTER TABLE '' + ' +
'QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + ''.'' + ' +
'QUOTENAME(OBJECT_NAME(i.object_id)) + @crlf + ' +
'''ADD '' + ' +
'CASE k.is_system_named ' +
'WHEN 0 THEN ''CONSTRAINT '' + QUOTENAME(k.name) + @crlf ' +
'ELSE '''' ' +
'END + ' +
'CASE k.type ' +
'WHEN ''UQ'' THEN ''UNIQUE'' ' +
'ELSE ''PRIMARY KEY'' ' +
'END + '' '' + ' +
'i.type_desc + @crlf + ' +
'kc.key_columns + @crlf ' +
'ELSE ' +
'''CREATE UNIQUE '' + i.type_desc + '' INDEX '' + ' +
'QUOTENAME(i.name) + @crlf + ' +
'''ON '' + ' +
'QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + ''.'' + ' +
'QUOTENAME(OBJECT_NAME(i.object_id)) + @crlf + ' +
'kc.key_columns + @crlf + ' +
'COALESCE ' +
'( ' +
'''INCLUDE '' + @crlf + ' +
'''( '' + @crlf + ' +
'STUFF ' +
'( ' +
'( ' +
'SELECT ' +
'( ' +
'SELECT ' +
''','' + @crlf + '' '' + QUOTENAME(c.name) AS [text()] ' +
'FROM sys.index_columns AS ic ' +
'JOIN sys.columns AS c ON ' +
'c.object_id = ic.object_id ' +
'AND c.column_id = ic.column_id ' +
'WHERE ' +
'ic.object_id = i.object_id ' +
'AND ic.index_id = i.index_id ' +
'AND ic.is_included_column = 1 ' +
'ORDER BY ' +
'ic.key_ordinal ' +
'FOR XML PATH(''''), TYPE ' +
').value(''.'', ''VARCHAR(MAX)'') ' +
'), ' +
'1, ' +
'3, ' +
''''' ' +
') + @crlf + ' +
''')'' + @crlf, ' +
''''' ' +
') ' +
'END + ' +
'''WITH '' + @crlf + ' +
'''('' + @crlf + ' +
''' PAD_INDEX = '' + ' +
'CASE CONVERT(VARCHAR, i.is_padded) ' +
'WHEN 1 THEN ''ON'' ' +
'ELSE ''OFF'' ' +
'END + '','' + @crlf + ' +
'CASE i.fill_factor ' +
'WHEN 0 THEN '''' ' +
'ELSE ' +
''' FILLFACTOR = '' + ' +
'CONVERT(VARCHAR, i.fill_factor) + '','' + @crlf ' +
'END + ' +
''' IGNORE_DUP_KEY = '' + ' +
'CASE CONVERT(VARCHAR, i.ignore_dup_key) ' +
'WHEN 1 THEN ''ON'' ' +
'ELSE ''OFF'' ' +
'END + '','' + @crlf + ' +
''' ALLOW_ROW_LOCKS = '' + ' +
'CASE CONVERT(VARCHAR, i.allow_row_locks) ' +
'WHEN 1 THEN ''ON'' ' +
'ELSE ''OFF'' ' +
'END + '','' + @crlf + ' +
''' ALLOW_PAGE_LOCKS = '' + ' +
'CASE CONVERT(VARCHAR, i.allow_page_locks) ' +
'WHEN 1 THEN ''ON'' ' +
'ELSE ''OFF'' ' +
'END + ' +
CASE @version
WHEN '2005' THEN ''
ELSE
''','' + @crlf + ' +
''' DATA_COMPRESSION = '' + ' +
'( ' +
'SELECT ' +
'CASE ' +
'WHEN MIN(p.data_compression_desc) =
MAX(p.data_compression_desc)
THEN MAX(p.data_compression_desc) ' +
'ELSE ''[PARTITIONS USE
MULTIPLE COMPRESSION TYPES]'' ' +
'END ' +
'FROM sys.partitions AS p ' +
'WHERE ' +
'p.object_id = i.object_id ' +
'AND p.index_id = i.index_id ' +
') '
END + '+ @crlf + ' +
''') '' + @crlf + ' +
'''ON '' + ds.data_space + '';'' + ' +
'@crlf + @crlf COLLATE database_default AS [-- Create Candidate Keys] ' +
'FROM sys.indexes AS i ' +
'LEFT OUTER JOIN sys.key_constraints AS k ON ' +
'k.parent_object_id = i.object_id ' +
'AND k.unique_index_id = i.index_id ' +
'CROSS APPLY ' +
'( ' +
'SELECT ' +
'''( '' + @crlf + ' +
'STUFF ' +
'( ' +
'( ' +
'SELECT ' +
'( ' +
'SELECT ' +
''','' + @crlf + '' '' + QUOTENAME(c.name) AS [text()] ' +
'FROM sys.index_columns AS ic ' +
'JOIN sys.columns AS c ON ' +
'c.object_id = ic.object_id ' +
'AND c.column_id = ic.column_id ' +
'WHERE ' +
'ic.object_id = i.object_id ' +
'AND ic.index_id = i.index_id ' +
'AND ic.key_ordinal > 0 ' +
'ORDER BY ' +
'ic.key_ordinal ' +
'FOR XML PATH(''''), TYPE ' +
').value(''.'', ''VARCHAR(MAX)'') ' +
'), ' +
'1, ' +
'3, ' +
''''' ' +
') + @crlf + ' +
''')'' ' +
') AS kc (key_columns) ' +
'CROSS APPLY ' +
'( ' +
'SELECT ' +
'QUOTENAME(d.name) + ' +
'CASE d.type ' +
'WHEN ''PS'' THEN ' +
'+ ' +
'''('' + ' +
'( ' +
'SELECT ' +
'QUOTENAME(c.name) ' +
'FROM sys.index_columns AS ic ' +
'JOIN sys.columns AS c ON ' +
'c.object_id = ic.object_id ' +
'AND c.column_id = ic.column_id ' +
'WHERE ' +
'ic.object_id = i.object_id ' +
'AND ic.index_id = i.index_id ' +
'AND ic.partition_ordinal = 1 ' +
') + ' +
''')'' ' +
'ELSE '''' ' +
'END ' +
'FROM sys.data_spaces AS d ' +
'WHERE ' +
'd.data_space_id = i.data_space_id ' +
') AS ds (data_space) ' +
'WHERE ' +
'i.object_id = @object_id ' +
'AND i.is_unique = 1 ' +
--filtered and hypothetical indexes cannot be candidate keys
CASE @version
WHEN '2008' THEN 'AND i.has_filter = 0 '
ELSE ''
END +
'AND i.is_hypothetical = 0 ' +
'AND i.is_disabled = 0 ' +
'ORDER BY ' +
'i.index_id '
EXEC sp_executesql
@sql,
N'@object_id INT, @crlf CHAR(2)',
@object_id, @crlf
SELECT
'ALTER TABLE ' +
QUOTENAME(OBJECT_SCHEMA_NAME(fk.parent_object_id)) + '.' +
QUOTENAME(OBJECT_NAME(fk.parent_object_id)) + @crlf +
CASE fk.is_not_trusted
WHEN 0 THEN 'WITH CHECK '
ELSE 'WITH NOCHECK '
END +
'ADD ' +
CASE fk.is_system_named
WHEN 0 THEN 'CONSTRAINT ' + QUOTENAME(name) + @crlf
ELSE ''
END +
'FOREIGN KEY ' + @crlf +
'( ' + @crlf +
STUFF
(
(
SELECT
(
SELECT
',' + @crlf + ' ' + QUOTENAME(c.name) AS [text()]
FROM sys.foreign_key_columns AS fc
JOIN sys.columns AS c ON
c.object_id = fc.parent_object_id
AND c.column_id = fc.parent_column_id
WHERE
fc.constraint_object_id = fk.object_id
ORDER BY
fc.constraint_column_id
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)')
),
1,
3,
''
) + @crlf +
') ' +
'REFERENCES ' +
QUOTENAME(OBJECT_SCHEMA_NAME(fk.referenced_object_id)) + '.' +
QUOTENAME(OBJECT_NAME(fk.referenced_object_id)) + @crlf +
'( ' + @crlf +
STUFF
(
(
SELECT
(
SELECT
',' + @crlf + ' ' + QUOTENAME(c.name) AS [text()]
FROM sys.foreign_key_columns AS fc
JOIN sys.columns AS c ON
c.object_id = fc.referenced_object_id
AND c.column_id = fc.referenced_column_id
WHERE
fc.constraint_object_id = fk.object_id
ORDER BY
fc.constraint_column_id
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)')
),
1,
3,
''
) + @crlf +
');' +
@crlf + @crlf COLLATE database_default AS [-- Create Referencing FKs]
FROM sys.foreign_keys AS fk
WHERE
referenced_object_id = @object_id
AND is_disabled = 0
ORDER BY
key_index_id
END

Step 4: Create a Stored Procedure to Script Drop Indexes and Relationships

Now you also need to create the drop scripts, this is the other half of Adam Machanic’s script.

CREATE PROC [dbo].[ScriptDropTableKeys]
@table_name SYSNAME
AS
BEGIN
SET NOCOUNT ON
--Note: Disabled keys and constraints are ignored
--TODO: Drop and re-create referencing XML indexes, FTS catalogs
DECLARE @crlf CHAR(2)
SET @crlf = CHAR(13) + CHAR(10)
DECLARE @version CHAR(4)
SET @version = SUBSTRING(@@VERSION, LEN('Microsoft SQL Server') + 2, 4)
DECLARE @object_id INT
SET @object_id = OBJECT_ID(@table_name)
DECLARE @sql NVARCHAR(MAX)
IF @version NOT IN ('2005', '2008')
BEGIN
RAISERROR('This script only supports SQL Server 2005 and 2008', 16, 1)
RETURN
END
SELECT
'ALTER TABLE ' +
QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' +
QUOTENAME(OBJECT_NAME(parent_object_id)) + @crlf +
'DROP CONSTRAINT ' + QUOTENAME(name) + ';' +
@crlf + @crlf COLLATE database_default AS [-- Drop Referencing FKs]
FROM sys.foreign_keys
WHERE
referenced_object_id = @object_id
AND is_disabled = 0
ORDER BY
key_index_id DESC
SET @sql = '' +
'SELECT ' +
'statement AS [-- Drop Candidate Keys] ' +
'FROM ' +
'( ' +
'SELECT ' +
'CASE ' +
'WHEN 1 IN (i.is_unique_constraint, i.is_primary_key) THEN ' +
'''ALTER TABLE '' + ' +
'QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + ''.'' + ' +
'QUOTENAME(OBJECT_NAME(i.object_id)) + @crlf + ' +
'''DROP CONSTRAINT '' + QUOTENAME(i.name) + '';'' + ' +
'@crlf + @crlf COLLATE database_default ' +
'ELSE ' +
'''DROP INDEX '' + QUOTENAME(i.name) + @crlf + ' +
'''ON '' + ' +
'QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + ''.'' + ' +
'QUOTENAME(OBJECT_NAME(object_id)) + '';'' + ' +
'@crlf + @crlf COLLATE database_default ' +
'END AS statement, ' +
'i.index_id ' +
'FROM sys.indexes AS i ' +
'WHERE ' +
'i.object_id = @object_id ' +
'AND i.is_unique = 1 ' +
--filtered and hypothetical indexes cannot be candidate keys
CASE @version
WHEN '2008' THEN 'AND i.has_filter = 0 '
ELSE ''
END +
'AND i.is_hypothetical = 0 ' +
'AND i.is_disabled = 0 ' +
') AS x ' +
'ORDER BY ' +
'index_id DESC '
EXEC sp_executesql
@sql,
N'@object_id INT, @crlf CHAR(2)',
@object_id, @crlf
END

Step 5: Bringing them all together

Now you have the two Stored Procedures, all you have to do is to loop though all the tables in your database and pass that as the parameter of the Stored Procedure. First we use ScriptCreateTableKeys.

DECLARE @TableName nvarchar(255)
DECLARE MyTableCursor Cursor
FOR
SELECT name FROM sys.tables WHERE [type] = 'U' and name <> 'sysdiagrams' ORDER BY name
OPEN MyTableCursor
FETCH NEXT FROM MyTableCursor INTO @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC ScriptCreateTableKeys @TableName
FETCH NEXT FROM MyTableCursor INTO @TableName
END
CLOSE MyTableCursor
DEALLOCATE MyTableCursor
Then let us use ScriptDropTableKeys:
DECLARE @TableName nvarchar(255)
DECLARE MyTableCursor Cursor
FOR
SELECT name FROM sys.tables WHERE [type] = 'U' and name <> 'sysdiagrams' ORDER BY name
OPEN MyTableCursor
FETCH NEXT FROM MyTableCursor INTO @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC ScriptDropTableKeys @TableName
FETCH NEXT FROM MyTableCursor INTO @TableName
END
CLOSE MyTableCursor
DEALLOCATE MyTableCursor

Just make sure when you execute them, output the results as text so you can easily copy and paste the results. Save the first results as “CreateKeysAndIndexes.sql” and the second as “DropKeysAndIndexes.sql”

Step 6: Run your saved scripts

In this order, run your scripts and wait for the results, time wait might vary depending on your database size. 1. DropKeysAndIndexes.sql 2. ChangeCollation.sql 3. CreateKeysAndIndexes.sql

License This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

[SQL]批量 更改字符集脚本,批量查询约束,批量查询索引的更多相关文章

  1. 在excel批量更改单元格类型后的批量刷新显示

    把E的东西变成完整显示 解决办法: 选中所需要更改的整列数据------>菜单栏的数据选项------>分列

  2. 带参方法的执行:普通方法的查询,可为空方法的查询。批量处理SQL语句。

    普通方法的查询: @Override public List<Map<String, Object>> selectSpentAmount(Integer MAT_TYPE_, ...

  3. StackExchange.Redis加载Lua脚本进行模糊查询的批量删除和修改

    前言 使用StackExchange.Redis没有直接相关的方法进行模糊查询的批量删除和修改操作,虽然可以通过Scan相关的方法进行模糊查询,例如:HashScan("hashkey&qu ...

  4. MS SQL批量生成作业脚本方法介绍总结

    在迁移或升级SQL Server数据库服务器时,很多场景下我们不能还原msdb,所以我们必须手工迁移SQL Server相关作业.如果手工生成每一个作业的脚本话,费时又费力,其实SQL Server中 ...

  5. 批量更改数据库表架构(生成sql后直接执行!)

    批量更改数据库表架构(生成sql后直接执行!) use my_test; --当前数据库 ), ), ), @NewSql VARCHAR(max), @Index INT; SET @SchemaO ...

  6. Sql批量添加,批量查询,批量删除,批量修改。mybatis都有对应标签

    Sql批量添加,批量查询,批量删除,批量修改.mybatis都有对应标签

  7. 批量更改数据库COLLATION

    企业内部有很多系统是繁体的,由于各方面的原因,公司目前正在实行简体化,但各系统中又有数据间的交换,所以系统只能一个一个的更改,以防同时出现过多的问题.由于原先数据库只能存储繁体,而原先已存在的数据则可 ...

  8. ubuntu批量更改文件权限

    重装系统之后,把文件从windows分区拷到linux分区发现所有文件的权限全是777,在终端下看到所有文件的颜色都很刺眼,文件有很多,一个一个改不现实,所以写了一段python脚本批量更改文件权限. ...

  9. linux下怎样批量更改文件后缀名

    今天又有同学问linux下怎样批量更改文件后缀名,这个问题被别人问到三次了,所以这里给出几个解决方法 一.rename解决 1.  Ubuntu系统下 rename 's//.c//.h/'  ./* ...

随机推荐

  1. 12款优秀 jQuery Ajax 分页插件和教程

    12款优秀 jQuery Ajax 分页插件和教程 在这篇文章中,我为大家收集了12个基于 jQuery 框架的 Ajax 分页插件,这些插件都提供了详细的使用教程和演示.Ajax 技术的出现使得 W ...

  2. Python 随机数,break,continue

    #-*- coding:utf-8 -*- #导入模块 import random #打印10以内的随机数 num = 5 while num > 0: #random.randint(0,10 ...

  3. TCP/IP和Socket的关系

    要写网络程序就必须用Socket,这是程序员都知道的.而且,面试的时候,我们也会问对方会不会Socket编程?一般来说,很多人都会说,Socket编程基本就是listen,accept以及send,w ...

  4. 关于Cocos2d-x的动作和动画

    1.动作,在cocos2d-x中有非常多种的动作,各种移动,旋转,缩放,淡入淡出....等等非常多,但是这些动作只是作用于节点,最常作用于的就是精灵节点.而且我们可以把很多个动作放进一个Sequenc ...

  5. 【转】C#调用WebService实例和开发

    一.基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术.是 ...

  6. Nodejs入门手记 (01):Hello World的WEB程序

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Allong,谢谢! “滚滚长江东逝水,浪花淘尽英雄.是非成败转头空.” - <临江仙·杨慎·明> 很熟悉的旋律,鸡汤了一下:高考是 ...

  7. (转)一种开源的跨平台视频开发框架:VideoLAN - VLC media player

    VLC原先是几个法国的大学生做的项目,后来他们把VLC作为了一个开源的项目,吸引了来自世界各国的很多优秀程序员来共同编写和维护VLC,才逐渐变成了现在这个样子.至于为什么叫VideoLan Clien ...

  8. 【Java面试题】11 什么是内部类?Static Nested Class 和 Inner Class的不同。

    Inner Class(内部类)定义在类中的类. (一般是JAVA的说法) Nested Class(嵌套类)是静态(static)内部类.(一般是C++的说法)静态内部类:1 创建一个static内 ...

  9. opengl wglsharelists

    原文地址:http://blog.csdn.net/webscaler/article/details/5873179 OpenGL 中用到多线程和多 render context 渲染的时候会用到 ...

  10. AOP技术应用和研究--AOP简单应用

    为了更好的理解AOP实践和体现AOP的优势.我们始终将OOP和AOP的比較贯穿到下文中.并在终于总结出AOP与OOP相比所拥有的长处,AOP的缺点以及AOP一般的使用场景. 1.1 问题空间到解空间的 ...