Is it possible to change collation of ALL tables of ALL databases of the server at the same time?
I find lots of scripts but only for ONE database at time. We have 100+ databases and I need to use a unique collation to all of them.
Can we list using some kind of script?
Thanks.
(Sorry for the bad english )
Obs1: If possible, I need to change columns collation too. we need ONE collation for everything !
Thanks friends.
EDITED:
Here i have a script that lists "all" tables of a database, and it shows me the code in results.
I need to do some kind of loop, because what i need is alter all tables and columns of all databases.
I can only run this code in a unique database.
DECLARE @collate SYSNAME
SELECT @collate = 'Latin1_General_CI_AS'
SELECT
'[' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + '] -> ' + c.name
, 'ALTER TABLE [' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + ']
ALTER COLUMN [' + c.name + '] ' +
UPPER(t.name) +
CASE WHEN t.name NOT IN ('ntext', 'text')
THEN '(' +
CASE
WHEN t.name IN ('nchar', 'nvarchar') AND c.max_length != -1
THEN CAST(c.max_length / 2 AS VARCHAR(10))
WHEN t.name IN ('nchar', 'nvarchar') AND c.max_length = -1
THEN 'MAX'
ELSE CAST(c.max_length AS VARCHAR(10))
END + ')'
ELSE ''
END + ' COLLATE ' + @collate +
CASE WHEN c.is_nullable = 1
THEN ' NULL'
ELSE ' NOT NULL'
END
FROM sys.columns c WITH(NOLOCK)
JOIN sys.objects o WITH(NOLOCK) ON c.[object_id] = o.[object_id]
JOIN sys.types t WITH(NOLOCK)
ON c.system_type_id = t.system_type_id AND c.user_type_id = t.user_type_id
WHERE t.name IN ('char', 'varchar', 'text', 'nvarchar', 'ntext', 'nchar')
AND c.collation_name != @collate
AND o.[type] = 'U'
EDIT2:
I was searching on the internet, and i found this magic proc: SP_MSFOREACHDB.
i was using sp_helptext to knwo how i could use it with my proc. but again, with no success.
EDIT 3: FINALLY I DID IT !!!
this is the proc i made:
DECLARE @collate SYSNAME
SELECT @collate = 'Latin1_General_CI_AS'
declare @cmd as nvarchar(4000)
declare @banco as varchar(100)
-- Bancos que serão consultados
Select name into #tmp from master.sys.databases Where name not in ('master', 'model', 'msdb',
'tempdb')
--while
-- Loop pelos bancos
While (Select count(1) from #tmp) > 0
begin
Select @banco = min(name) from #tmp
set @cmd = '
use [' + @banco + ' ]
insert into collate_adm.dbo.tblCollateScript
SELECT ''?'' as Banco,
''['' + SCHEMA_NAME(o.[schema_id]) + ''].['' + o.name + ''] -> '' + c.name
, '' use [' + @banco + ' ] ALTER TABLE ['' + SCHEMA_NAME(o.[schema_id]) + ''].['' +
o.name + '']
ALTER COLUMN ['' + c.name + ''] '' +
UPPER(t.name) +
CASE WHEN t.name NOT IN (''ntext'', ''text'')
THEN ''('' +
CASE
WHEN t.name IN (''nchar'', ''nvarchar'') AND c.max_length !=
-1
THEN CAST(c.max_length / 2 AS VARCHAR(10))
WHEN t.name IN (''nchar'', ''nvarchar'') AND c.max_length =
-1
THEN ''MAX''
ELSE CAST(c.max_length AS VARCHAR(10))
END + '')''
ELSE ''''
END + '' COLLATE Latin1_General_CI_AS '' +
CASE WHEN c.is_nullable = 1
THEN '' NULL''
ELSE '' NOT NULL''
END
FROM sys.columns c WITH(NOLOCK)
JOIN sys.objects o WITH(NOLOCK) ON c.[object_id] = o.[object_id]
JOIN sys.types t WITH(NOLOCK) ON c.system_type_id = t.system_type_id AND c.user_type_id =
t.user_type_id
WHERE t.name IN (''char'', ''varchar'', ''text'', ''nvarchar'', ''ntext'', ''nchar'')
AND c.collation_name != ''Latin1_General_CI_AS''
AND o.[type] = ''U''
'
set @cmd = replace(replace(@cmd,'?', @banco) , 'XXXcollateXXX', @collate)
begin try
exec sp_executeSQL @cmd -- Executa comando gerado pelo script
end try
begin catch
insert into tblCollateScript (rotina, script,Data) values ('pr_BuscaCotas', @cmd,
GETDATE())
end catch
Delete from #tmp Where name = @banco
end
drop table #tmp
end
Thank you guys for everything !