0

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 !

Racer SQL
  • 207
  • 1
  • 3
  • 14
  • You'll need to use dynamic SQL. Can't provide any more information than that without code you're trying to use or which RDBMS you're using. – Bacon Bits Nov 04 '14 at 15:23
  • Hello! Thanks for the help. I dont have a code. im new in this world and i'm not so good in code yet. And sorry...im using SQL Server 2008. – Racer SQL Nov 05 '14 at 16:31
  • I mean the script code you're using. We'll need to see it. StackOverflow helps with questions and problems on existing code. We don't write new code, we just expand on what you already have. – Bacon Bits Nov 05 '14 at 17:01
  • Really really sorry !! im getting used to it. I edited my post. hope it helps ! Again, thanks a lot for the patience. – Racer SQL Nov 06 '14 at 17:30
  • You may want to take a look at [this](http://www.codeproject.com/Articles/302405/The-Easy-way-of-changing-Collation-of-all-Database). – Bacon Bits Nov 07 '14 at 18:09
  • Hey ! thanks for helping. actually, this is what i did with some programmers helping me: ( see edited post above ) – Racer SQL Nov 11 '14 at 18:45

0 Answers0