2009-08-25 12 views
7

Tengo una base de datos (Sql Server 2005) donde hay docenas de tablas, cada una de las cuales tiene varias columnas (en promedio 10-20) con el tipo de datos establecido en nvarchar (max) Este es un rendimiento absolutamente negativo (algunas de estas columnas se utilizan para uniones y algunas de las tablas tienen más de 100K filas). Me gustaría cambiar todas estas columnas para que sean varchar (250). ¿Cuál sería la mejor manera de automatizar esto? (Podría usar Management Studio, o podría crear una utilidad para realizar esto a través de un sitio web ASP.net que tenga acceso a la base de datos, lo que sea más fácil).Cómo cambiar todas las columnas Sql de un tipo de datos en otro

Respuesta

9

Aquí hay un guión de trabajo que utiliza INFORMATION_SCHEMA.COLUMNS para encontrar todos los *varchar(max) columnas y los convierte en 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 

Este es el único uso de cursores que alguna vez condonar, pero es una buena. Esencialmente, encuentra todos los *varchar(max), construye la declaración alter y luego la ejecuta usando sp_executesql.

¡Disfrútalo!

+0

Esto no funciona a la perfección ya que también trae columnas desde las vistas –

+0

@Yaakov: ¡Solucionado! – Eric

+0

Ahora, ¿cómo eliminar las restricciones y volver a ponerlas al hacer esto, ya que no podemos alterar las cols con una restricción en su lugar? – JosephK

0

Creo que la mejor manera de hacer esta tarea es generar script para la base de datos actual y luego reemplazar nvarchar (max) con varchar (250) en el archivo de texto, y luego crear la nueva base de datos. después de eso, use las utilidades de importación/exportación para transferir los datos a la nueva base de datos.

+0

Esto no funciona - SSIS devolverá un mensaje de error que indica que los metadatos de la columna no coinciden entre las tablas de origen y de destino –

3

Usted puede encontrar fácilmente, 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 

Así que ahora sólo agarrar los resultados de la consulta y ejecutarlo.

Rob

+1

También podría valer la pena mencionar ... si pone declare @qry nvarchar (max), y seleccione @qry = (.... para xml path ('')); exec sp_executesql @qry; - Puedes hacerlo todo en un solo paso. El ... es la consulta actual que tengo. Pero entonces no puedes 'sanidad' comprobarlo tan bien. –

+0

¿Necesita tener en cuenta la invalidación de columna? ¿Esto alterará las columnas para ser anulables porque no especifica de ninguna manera? –

Cuestiones relacionadas