2009-08-25 11 views
7

Ho un database (Sql Server 2005) in cui ci sono dozzine di tabelle, ognuna delle quali ha un numero di colonne (in media 10-20) con datatype impostato su nvarchar (max). Si tratta di prestazioni assolutamente in fase di soppressione (alcune di queste colonne vengono utilizzate per i join e alcune tabelle hanno righe di 100K +). Vorrei cambiare tutte queste colonne per essere varchar (250). Quale sarebbe il modo migliore per automatizzare questo? (Potrei usare Management Studio, o potrei creare un'utilità per farlo attraverso un sito Web ASP.net che ha accesso al db, a seconda di quale sia più semplice).Come modificare tutte le colonne Sql di un DataType in un altro

risposta

9

Ecco uno script di lavoro che utilizza INFORMATION_SCHEMA.COLUMNS per trovare tutti i *varchar(max) colonne e li converte in varchar(255):

declare @schema nvarchar(255) 
declare @table nvarchar(255) 
declare @col nvarchar(255) 
declare @dtype nvarchar(255) 
declare @sql nvarchar(max) 

declare maxcols cursor for 
select 
    c.TABLE_SCHEMA, 
    c.TABLE_NAME, 
    c.COLUMN_NAME, 
    c.DATA_TYPE 
from 
INFORMATION_SCHEMA.COLUMNS c 
inner join INFORMATION_SCHEMA.TABLES t on 
    c.TABLE_CATALOG = t.TABLE_CATALOG 
    and c.TABLE_SCHEMA = t.TABLE_SCHEMA 
    and c.TABLE_NAME = t.TABLE_NAME 
    and t.TABLE_TYPE = 'BASE TABLE' 
where 
    c.DATA_TYPE like '%varchar' 
    and c.CHARACTER_MAXIMUM_LENGTH = -1 

open maxcols 

fetch next from maxcols into @schema, @table, @col, @dtype 

while @@FETCH_STATUS = 0 
begin 
    set @sql = 'alter table [' + @schema + '].[' + @table + 
     '] alter column [' + @col + '] ' + @dtype + '(255)' 
    exec sp_executesql @sql 

    fetch next from maxcols into @schema, @table, @col, @dtype 
end 

close maxcols 
deallocate maxcols 

Questo è circa il solo uso di cursori che io abbia mai giustifico, ma è buono In sostanza, trova tutto il *varchar(max), crea l'istruzione alter e quindi la esegue utilizzando sp_executesql.

Divertiti!

+0

Questo non funziona perfettamente poiché introduce anche colonne dalle viste –

+0

@Yaakov: corretto! – Eric

+0

Ora, come eliminare i vincoli e rimetterli indietro mentre si fa questo, dal momento che non possiamo alterare i cols con un vincolo in atto? – JosephK

0

Penso che il modo migliore per eseguire questa attività sia generare lo script per il database corrente e quindi sostituire nvarchar (max) con varchar (250) nel file di testo e quindi creare il nuovo database. successivamente utilizzare le utilità di importazione/esportazione per trasferire i dati nel nuovo database.

+0

Questo non funziona - SSIS restituirà un messaggio di errore che indica che i metadati della colonna non corrispondono tra le tabelle di origine e di destinazione –

3

Si può facilmente trovare, usando:

select 'alter table ' + quotename(o.name) + ' alter column ' + quotename(c.name) + ' varchar(250); ' 
from sys.columns c 
    join 
    sys.objects o 
    on o.object_id = c.object_id 
where o.type = 'U' 
and c.user_type_id = 231 
and c.max_length = -1 

Quindi ora basta afferrare i risultati della query ed eseguirlo.

Rob

+1

Potrebbe anche essere opportuno menzionare ... se si inserisce dichiarare @qry nvarchar (max), e selezionare @qry = (.... per il percorso xml ('')); exec sp_executesql @qry; - Puoi fare tutto in un solo passaggio. Il .... è la domanda corrente che ho. Ma allora non puoi 'controllare l'equilibrio' così bene. –

+0

È necessario tenere conto della nullità della colonna? Questo modificherà le colonne come annullabili perché non specifica in alcun modo? –

Problemi correlati