Change collation of ALL tables of ALL databases at the same time

99封情书 提交于 2019-12-13 05:16:27

问题


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 !

来源:https://stackoverflow.com/questions/26713336/change-collation-of-all-tables-of-all-databases-at-the-same-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!