[SQL]批量 更改字符集脚本,批量查询约束,批量查询索引
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]批量 更改字符集脚本,批量查询约束,批量查询索引的更多相关文章
- 在excel批量更改单元格类型后的批量刷新显示
把E的东西变成完整显示 解决办法: 选中所需要更改的整列数据------>菜单栏的数据选项------>分列
- 带参方法的执行:普通方法的查询,可为空方法的查询。批量处理SQL语句。
普通方法的查询: @Override public List<Map<String, Object>> selectSpentAmount(Integer MAT_TYPE_, ...
- StackExchange.Redis加载Lua脚本进行模糊查询的批量删除和修改
前言 使用StackExchange.Redis没有直接相关的方法进行模糊查询的批量删除和修改操作,虽然可以通过Scan相关的方法进行模糊查询,例如:HashScan("hashkey&qu ...
- MS SQL批量生成作业脚本方法介绍总结
在迁移或升级SQL Server数据库服务器时,很多场景下我们不能还原msdb,所以我们必须手工迁移SQL Server相关作业.如果手工生成每一个作业的脚本话,费时又费力,其实SQL Server中 ...
- 批量更改数据库表架构(生成sql后直接执行!)
批量更改数据库表架构(生成sql后直接执行!) use my_test; --当前数据库 ), ), ), @NewSql VARCHAR(max), @Index INT; SET @SchemaO ...
- Sql批量添加,批量查询,批量删除,批量修改。mybatis都有对应标签
Sql批量添加,批量查询,批量删除,批量修改.mybatis都有对应标签
- 批量更改数据库COLLATION
企业内部有很多系统是繁体的,由于各方面的原因,公司目前正在实行简体化,但各系统中又有数据间的交换,所以系统只能一个一个的更改,以防同时出现过多的问题.由于原先数据库只能存储繁体,而原先已存在的数据则可 ...
- ubuntu批量更改文件权限
重装系统之后,把文件从windows分区拷到linux分区发现所有文件的权限全是777,在终端下看到所有文件的颜色都很刺眼,文件有很多,一个一个改不现实,所以写了一段python脚本批量更改文件权限. ...
- linux下怎样批量更改文件后缀名
今天又有同学问linux下怎样批量更改文件后缀名,这个问题被别人问到三次了,所以这里给出几个解决方法 一.rename解决 1. Ubuntu系统下 rename 's//.c//.h/' ./* ...
随机推荐
- FastDFS 安装步骤
nginx01 121nginx02 122 tracker01 131tracker02 132 storage01 141storage0 ...
- SSI——服务器端嵌入
服务器端嵌入:Server Side Include,是一种类似于ASP的基于服务器的网页制作技术.大多数(尤其是基于Unix平台)的WEB服务器如Netscape Enterprise Server ...
- Deep Reinforcement Learning from Self-Play in Imperfect-Information Games
Heinrich, Johannes, and David Silver. "Deep reinforcement learning from self-play in imperfect- ...
- Python之多进程
1.Pool的用法 #!/usr/bin/env python # -*- coding: utf-8 -*- ''' @author: Shiyu Huang @contact: huangsy13 ...
- 【转】WCF入门教程五[WCF的通信模式]
一.概述 WCF在通信过程中有三种模式:请求与答复.单向.双工通信.以下我们一一介绍. 二.请求与答复模式 描述: 客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务 ...
- 散货:null 强转 和 iOS null崩溃
问题1 在看 SpringMVC源码剖析(五)-消息转换器HttpMessageConverter 的时候,在 org.springframework.web.servlet.mvc.method ...
- native生成策略:由Hibernate根据所使用的数据库支持能力从identity、sequence或者等生成策略中选择一种
increment生成策略:当Hibernate准备在数据库表中插入一条新记录时,首先从数据库表中获取当前主键字段的最大值,然后在最大值基础上加1,作为当前持久化对象的标识符属性值.这种策略即incr ...
- (转)I,P,B帧和PTS,DTS的关系
基本概念: I frame :帧内编码帧 又称intra picture,I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象. ...
- linux下常用FTP命令 1. 连接ftp服务器
1. 连接ftp服务器 格式:ftp [hostname| ip-address] a)在linux命令行下输入: ftp 192.168.1.1 b)服务器询问你用户名和密码,分别输入用户名和相应密 ...
- PHP实现金额数字转换成大写函数
<?php header("Content-Type:text/html;charset=utf-8"); function num_to_upper($num) { $d ...