2009-08-25 5 views
7

Mam bazę danych (Sql Server 2005), gdzie istnieją dziesiątki tabel, z których każda ma pewną liczbę kolumn (średnio 10-20) z typem danych ustawionym na nvarchar (max). Jest to absolutnie zabójcza wydajność (niektóre z tych kolumn są używane do łączenia, a niektóre z tabel mają 100K + wiersze). Chciałbym zmienić wszystkie te kolumny na varchar (250). Jaki byłby najlepszy sposób na zautomatyzowanie tego? (Mógłbym użyć Management Studio, lub mógłbym stworzyć narzędzie do wykonania tego przez stronę ASP.net, która ma dostęp do bazy danych, w zależności od tego, która z nich jest łatwiejsza).Jak zmienić wszystkie kolumny SQL jednego DataType na inny

Odpowiedz

9

Oto skrypt roboczego, który wykorzystuje INFORMATION_SCHEMA.COLUMNS znaleźć wszystkie *varchar(max) kolumn i konwertuje je do 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 

Jest to jedyna wykorzystaniem kursorów że kiedykolwiek tolerować, ale ten jest dobry. Zasadniczo znajduje wszystkie *varchar(max), buduje oświadczenie alter, a następnie wykonuje go przy użyciu sp_executesql.

Ciesz się!

+0

To nie działa idealnie, ponieważ powoduje także wyświetlanie kolumn z widoków –

+0

@Yaakov: Naprawiono! – Eric

+0

Teraz, jak zrzucać ograniczenia i odkładać je, robiąc to, ponieważ nie możemy zmienić kolców z obowiązującym ograniczeniem? – JosephK

0

Myślę, że najlepszym sposobem na zrobienie tego zadania jest wygenerowanie skryptu dla bieżącej bazy danych, a następnie zamiana nvarchar (max) na varchar (250) w pliku tekstowym, a następnie utworzenie nowej bazy danych. następnie użyj narzędzi do importu/eksportu, aby przenieść dane do nowej bazy danych.

+0

To nie działa - SSIS zwróci komunikat o błędzie z informacją, że metadane kolumny nie pasują między tabelą źródłową a docelową –

3

Można łatwo je znaleźć, używając:

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 

Więc teraz po prostu chwyć wyniki zapytania i uruchomić go.

Rob

+1

Może warto również wspomnieć ... jeśli umieścisz opcję deklaruj @ qry nvarchar (max), i wybierz @qry = (.... dla ścieżki xml ('')); exec sp_executesql @qry; - Możesz zrobić to wszystko w jednym kroku. The .... to aktualne zapytanie, które mam. Ale wtedy nie można tak dobrze "sprawdzić". –

+0

Czy należy wziąć pod uwagę opcję zerowania kolumny? Czy to zmieni kolumny, które mają być zerowane, ponieważ nie określa w żaden sposób? –