generated from mg0x7BE/repository-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCollation.sql
More file actions
258 lines (221 loc) · 8.24 KB
/
Collation.sql
File metadata and controls
258 lines (221 loc) · 8.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
/**********************************************************************************************/
-- Returns tables and user-defined table types with their column collations
SELECT
'Table' AS ObjectType,
TABLE_SCHEMA AS SchemaName,
TABLE_NAME AS ObjectName,
COLUMN_NAME AS ColumnName,
DATA_TYPE AS DataType,
COLLATION_NAME AS Collation
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
COLLATION_NAME IS NOT NULL
UNION ALL
SELECT
'User-Defined Table Type' AS ObjectType,
SCHEMA_NAME(tt.schema_id) AS SchemaName,
tt.name AS ObjectName,
c.name AS ColumnName,
TYPE_NAME(c.system_type_id) AS DataType,
c.collation_name AS Collation
FROM
sys.table_types AS tt
INNER JOIN
sys.columns AS c ON c.object_id = tt.type_table_object_id
WHERE
c.collation_name IS NOT NULL
ORDER BY
ObjectType,
SchemaName,
ObjectName,
ColumnName;
/**********************************************************************************************/
-- Check database-level and column-level collation for the entire instance
IF OBJECT_ID('tempdb..#CollationStats') IS NOT NULL
DROP TABLE #CollationStats;
CREATE TABLE #CollationStats (
ServerName NVARCHAR(128),
DatabaseName NVARCHAR(128),
Collation NVARCHAR(128),
CollationCount INT,
SourceType NVARCHAR(50)
);
INSERT INTO #CollationStats (ServerName, DatabaseName, Collation, CollationCount, SourceType)
SELECT
@@SERVERNAME AS ServerName,
d.name AS DatabaseName,
d.collation_name AS Collation,
0 AS CollationCount,
'Database' AS SourceType
FROM sys.databases d
WHERE d.name not in ('tempdb','msdb','ssisdb')
GROUP BY d.name, d.collation_name;
DECLARE @SQL NVARCHAR(MAX) = '';
SELECT @SQL = @SQL +
'USE [' + name + ']; ' +
'INSERT INTO #CollationStats (ServerName, DatabaseName, Collation, CollationCount, SourceType) ' +
-- Column collations
'SELECT ' +
'@@SERVERNAME AS ServerName, ' +
'''' + name + ''' AS DatabaseName, ' +
'c.collation_name AS Collation, ' +
'COUNT(*) AS CollationCount, ' +
'''Columns'' AS SourceType ' +
'FROM sys.tables t ' +
'INNER JOIN sys.schemas s ON t.schema_id = s.schema_id ' +
'INNER JOIN sys.columns c ON t.object_id = c.object_id ' +
'WHERE t.type = ''U'' ' +
'AND c.collation_name IS NOT NULL ' +
'GROUP BY c.collation_name ' +
-- Table type collations
'UNION ALL ' +
'SELECT ' +
'@@SERVERNAME AS ServerName, ' +
'''' + name + ''' AS DatabaseName, ' +
'c.collation_name AS Collation, ' +
'COUNT(*) AS CollationCount, ' +
'''Table Types'' AS SourceType ' +
'FROM sys.table_types tt ' +
'INNER JOIN sys.columns c ON c.object_id = tt.type_table_object_id ' +
'WHERE c.collation_name IS NOT NULL ' +
'GROUP BY c.collation_name; '
FROM sys.databases
WHERE state = 0 AND name not in ('tempdb','msdb','ssisdb');
EXEC sp_executesql @SQL;
SELECT
ServerName,
DatabaseName,
SourceType,
CASE WHEN (SourceType = 'Database') THEN 'Database' ELSE CONVERT(nvarchar(255), CollationCount) END as CollationCount,
Collation
FROM #CollationStats
ORDER BY 1,2,3,5
DROP TABLE #CollationStats;
/**********************************************************************************************/
-- Column-level collation details
use my_database;
SELECT
@@SERVERNAME AS ServerName,
db_name() as DatabaseName,
s.name AS SchemaName,
t.name AS TableName,
c.name AS ColumnName,
ty.name AS DataType,
c.collation_name AS Collation
FROM sys.tables t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN sys.columns c ON t.object_id = c.object_id
INNER JOIN sys.types ty ON c.user_type_id = ty.user_type_id
WHERE c.collation_name = 'Latin1_General_BIN'
AND t.type = 'U' -- User Table
AND ty.is_user_defined <> 1
ORDER BY 1,2,3,4,5
/**********************************************************************************************/
-- Change database collation
ALTER DATABASE my_database SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
ALTER DATABASE my_database
COLLATE Latin1_General_BIN;
GO
ALTER DATABASE my_database SET MULTI_USER;
GO
/**********************************************************************************************/
-- Change collation on column-level
use my_database;
SELECT
s.name AS SchemaName,
t.name AS TableName,
c.name AS ColumnName,
ty.name AS DataType,
c.max_length AS DataMaxLength,
c.collation_name AS Collation,
'ALTER TABLE [' + s.name + '].[' + t.name + '] ALTER COLUMN [' + c.name + '] ' +
ty.name +
CASE
WHEN c.max_length = -1 THEN '(MAX)'
WHEN ty.name IN ('char', 'varchar', 'nchar', 'nvarchar') THEN '(' + CAST(c.max_length / (CASE WHEN ty.name IN ('nchar', 'nvarchar') THEN 2 ELSE 1 END) AS VARCHAR(10)) + ')'
ELSE ''
END +
' COLLATE Latin1_General_BIN ' + CASE WHEN c.is_nullable = 0 THEN ' NOT NULL' ELSE ' NULL' END AS AlterScript
FROM sys.tables t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN sys.columns c ON t.object_id = c.object_id
INNER JOIN sys.types ty ON c.user_type_id = ty.user_type_id
WHERE c.collation_name <> 'Latin1_General_BIN'
AND t.type = 'U' -- User Table
AND ty.is_user_defined <> 1
ORDER BY 1,2,3
/**********************************************************************************************/
-- Find object
SELECT
o.name AS ObjectName,
SCHEMA_NAME(o.schema_id) AS SchemaName,
o.type_desc AS ObjectType,
o.create_date AS CreationDate,
o.modify_date AS ModificationDate,
m.definition AS ObjectDefinition
FROM
sys.objects o
LEFT JOIN
sys.sql_modules m ON o.object_id = m.object_id
WHERE
o.name LIKE '%fnMyFunction%'
AND o.type IN ('FN', 'IF', 'TF', 'P', 'V', 'U', 'TR')
ORDER BY
o.name;
/**********************************************************************************************/
-- Find column
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'MyColumn'
AND TABLE_NAME LIKE '%MyTable%';
/**********************************************************************************************/
-- Change collation on column-level (uncomment sp_executesql section)
use my_database
IF OBJECT_ID('tempdb..#AlterScripts') IS NOT NULL
DROP TABLE #AlterScripts;
CREATE TABLE #AlterScripts (
ID INT IDENTITY(1,1),
AlterScript NVARCHAR(MAX)
);
INSERT INTO #AlterScripts (AlterScript)
SELECT
'ALTER TABLE [' + s.name + '].[' + t.name + '] ALTER COLUMN [' + c.name + '] ' +
ty.name +
CASE
WHEN c.max_length = -1 THEN '(MAX)'
WHEN ty.name IN ('char', 'varchar', 'nchar', 'nvarchar') THEN '(' + CAST(c.max_length / (CASE WHEN ty.name IN ('nchar', 'nvarchar') THEN 2 ELSE 1 END) AS VARCHAR(10)) + ')'
ELSE ''
END +
' COLLATE Latin1_General_BIN ' +
CASE WHEN c.is_nullable = 0 THEN ' NOT NULL' ELSE ' NULL' END AS AlterScript
FROM sys.tables t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN sys.columns c ON t.object_id = c.object_id
INNER JOIN sys.types ty ON c.user_type_id = ty.user_type_id
WHERE c.collation_name <> 'Latin1_General_BIN'
AND t.type = 'U' -- User Table
AND ty.is_user_defined <> 1
ORDER BY s.name, t.name, c.name;
DECLARE @CurrentScript NVARCHAR(MAX);
DECLARE @CurrentID INT;
DECLARE @MaxID INT;
SELECT @MaxID = MAX(ID) FROM #AlterScripts;
SET @CurrentID = 1;
WHILE @CurrentID <= @MaxID
BEGIN
SELECT @CurrentScript = AlterScript
FROM #AlterScripts
WHERE ID = @CurrentID;
BEGIN TRY
-- EXEC sp_executesql @CurrentScript;
-- PRINT 'OK: ' + @CurrentScript;
END TRY
BEGIN CATCH
PRINT 'Error in: ' + @CurrentScript;
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
SET @CurrentID = @CurrentID + 1;
END;
DROP TABLE #AlterScripts;