2009-08-25 41 views
7

我有一個數據庫(Sql Server 2005),其中有數十個表,其中每個表都有許多列(平均爲10-20),數據類型設置爲nvarchar (最大值)。這絕對是殺死性能(其中一些列用於連接,一些表有100K +行)。我想將所有這些列更改爲varchar(250)。什麼是自動執行此操作的最佳方式? (我可以使用Management Studio,或者我可以通過可訪問數據庫的ASP.net網站創建一個實用程序來執行此操作,無論哪個更容易)。如何將一個DataType的所有Sql列更改爲另一個

回答

9

下面是一個使用INFORMATION_SCHEMA.COLUMNS找到所有*varchar(max)列,並將它們轉換爲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 

這是他們唯一的使用,我曾經縱容遊標,但這是一個很好的。基本上,它找到所有*varchar(max),生成alter語句,然後使用sp_executesql執行它。

享受!

+0

這不起作用,因爲它也帶來了視圖列 – 2009-08-25 11:26:27

+0

@Yaakov:修正! – Eric 2009-08-25 11:44:41

+0

現在,如何在執行此操作時刪除約束條件並將它們放回原處,因爲我們無法通過約束來改變cols? – JosephK 2016-09-08 14:59:19

0

我認爲完成此任務的最佳方法是爲當前數據庫生成腳本,然後在文本文件上用varchar(250)替換nvarchar(max),然後創建新數據庫。之後使用導入/導出實用程序將數據傳輸到新數據庫。

+0

這不起作用 - SSIS將返回一條錯誤消息,指出列元數據在源表和目標表之間不匹配 – 2009-08-25 13:17:18

3

你可以很容易找到它們,使用:

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 

所以現在只要抓住你的查詢結果,並運行它。

羅布

+1

值得一提的是......如果您將declare @qry nvarchar(max)並選擇@qry =(.... for xml path('')); exec sp_executesql @qry; - 你可以一步到位。 ....是我目前的查詢。但那麼你不能'理智地檢查'它如此之好。 – 2009-08-25 11:26:16

+0

您是否需要考慮列可空性?這是否會將列更改爲空,因爲它沒有指定任何一種方式? – 2012-03-20 17:04:25

相關問題