Paso de Nvarchar a Varchar en toda la base de datos.

08/04/2006 - 18:41 por José Manuel Blanes Pacheco | Informe spam
Hola grupo:

Tengo una base en producción de 20 GB con casi cien tablas y todas ellas con
muchas columnas de tipo nvarchar, nchar y ntext y ahora la nueva versión de
la aplicación que la explota, una aplicación de GIS, no puede tratar con
columnas de datos de tipo Unicode. Así que debo pasarlas a su
correspondiente tipo de datos con caracteres estandar.

El problema es el elevado número de tablas y sus correspondientes campos que
no puedo, evidentemente cambiar a mano. Además existen objetos dependientes,
tales como vistas, índices, restricciones de integridad referencial y de
clave primaria, procedimientos almacenados, permisos sobre tablas,
etc...

Así pues debo hacerlo automático. He pensado en crearme un script de
generación de una base de datos completa y luego mediante un "buscar y
reeemplazar", sustituir en el script todas las referencias a nvarchar a
varchar. Luego pasar el script sobre una base de datos de prueba y pasar los
datos mediante un DTS de la original a la de prueba.

¿Es esto lo más correcto? ¿Existe alguna otra manera?

Gracias anticipadas por todas vuestras respuestas.

Preguntas similare

Leer las respuestas

#6 DosFlores
10/04/2006 - 16:43 | Informe spam
Está claro, también se podrían leer los índices afectados y borrarlos para
luego volver a crearlos en el mismo script, aunque eso ya depende del tiempo
que se quiera emplear en la tarea de hacerlo.

Un saludo
Oscar Montesinos

"Alejandro Mesa" escribió en el
mensaje news:
Oscar,

Gracias por compartir el codigo con el grupo.

Fijate en este ejemplo donde se trata de alterar una columna que forma
parte
de la llave de un indice.

use northwind
go

create table t1(c1 nvarchar(15))
go

create nonclustered index t1_c1_nu_nc_idx
on t1(c1 asc)
go

alter table t1
alter column c1 varchar(15)
go

drop table t1
go

SQL Server reporta un error al tratar de hacer el "alter table".

Server: Msg 5074, Level 16, State 8, Line 2
The index 't1_c1_nu_nc_idx' is dependent on column 'c1'.
Server: Msg 4922, Level 16, State 1, Line 2
ALTER TABLE ALTER COLUMN c1 failed because one or more objects access this
column.

Crear el script que mencionas, no es suficiente para cambiar todas la s
columnas nvarchar hacia varchar.


AMB


"DosFlores" wrote:

Prueba este generador de código T-SQL, si no entiendes algo me lo dices.

DECLARE @cmds AS VARCHAR(255)
DECLARE @cmdstr AS VARCHAR(255)

select @cmds = 'echo --Fichero de actualización > c:\Update.sql'
exec @cmdstr = master..xp_cmdshell @cmds

DECLARE @tabla AS VARCHAR(255)
DECLARE @columna AS VARCHAR(255)
DECLARE @longitud AS INT

DECLARE crs CURSOR FOR
SELECT so.name,sc.name,sc.length
FROM syscolumns AS sc INNER JOIN sysobjects AS so ON
sc.id=so.id AND
sc.xtype#1 AND so.xtype='U'
OPEN crs
FETCH NEXT FROM crs INTO @tabla,@columna,@longitud
WHILE (@@Fetch_Status=0)
BEGIN
select @cmds = 'echo ALTER TABLE '+@tabla+' >> c:\Update.sql'
exec @cmdstr = master..xp_cmdshell @cmds
select @cmds = 'echo ALTER COLUMN '+@columna+' >>
c:\Update.sql'
exec @cmdstr = master..xp_cmdshell @cmds
select @cmds = 'echo VARCHAR('+STR(@longitud)+') NOT NULL >>
c:\Update.sql'
exec @cmdstr = master..xp_cmdshell @cmds

FETCH NEXT FROM crs INTO @tabla,@columna,@longitud
END
CLOSE crs
DEALLOCATE crs

Un saludo
Oscar Montesinos

"Alejandro Mesa" escribió en el
mensaje news:
> Pacheco,
>
> El problema grave aca es que no se puede alterar una columna que
> participa
> en un indice, restriccion, etc. Debes primero borrar el indice,
> restriccion,
> etc. Creo que la opcion primera por la que optastes es viable. Crea el
> script
> solo de las tablas, sin indices, llaves primarias, llaves foraneas,
> etc.
> (simplemente la estrutura de las tablas) y crea una nueva db. Antes de
> ejecutar el script, editalo con tu programa de preferencia y cambia
> todas
> las
> referencias de nchar/nvarchar/ntext por char/varchar/text y salvas el
> script.
> Ejecuta el script en la nueva db para crear las tablas y crea los
> paquetes
> dts necesarios para copiar la data. Luego creas un script para crear
> claves
> primarias, foraneas y cualquer otro tipo de restricciones y/o indices.
> Ejecutas el script en la db nueva despues de haber copiado la data.
>
> Sacas un backup de la db original y la eliminas. saca un backup de la
> nueva
> db nueva y la renombras con sp_renamedb. Si deseas cambiar los nombres
> logicos de los archivos de data y/o log, puedes usar "alter database".
> Si
> deseas cambiar los nombres fisicos de los archivos de data y/o log
> puedes
> sacar un backup y despues hacer un restore con la opcion "with move".
>
>
> AMB
>
> "José Manuel Blanes Pacheco" wrote:
>
>> Sería muy amable por tu parte que me lo pasaras para que me sirviera
>> de
>> guía.
>>
>> Muchas gracias.
>>
>>
>> "DosFlores" escribió en el mensaje
>> news:
>> > Puedes crear un script que te haga la modificación en todas las
>> > columnas.
>> >
>> > Se puede utilizar un cursor para:
>> >
>> > 1º Hacer un Select en syscolumns de todas las columnas unicode
>> > 2º Formas una cadena con la instrucción de modificación de la
>> > columna
>> > añadiendo el nombre de la columna y tabla a modificar.
>> > 3º Le añades ' >Fichero.sql' a la cadena formada con la instrucción
>> > 4º Insertas a un fichero la instrucción con con
>> > master.dbo.xp_cmdshell
>> > @tuInstruccion
>> >
>> > Tengo un script hecho por algún lado, si lo necesitas te lo puedo
>> > pasar.
>> >
>> > Un saludo
>> > Oscar Montesinos.
>> >
>> > "José Manuel Blanes Pacheco" escribió en el
>> > mensaje
>> > news:nIRZf.1829$
>> >> Hola grupo:
>> >>
>> >> Tengo una base en producción de 20 GB con casi cien tablas y todas
>> >> ellas
>> >> con muchas columnas de tipo nvarchar, nchar y ntext y ahora la
>> >> nueva
>> >> versión de la aplicación que la explota, una aplicación de GIS, no
>> >> puede
>> >> tratar con columnas de datos de tipo Unicode. Así que debo pasarlas
>> >> a
>> >> su
>> >> correspondiente tipo de datos con caracteres estandar.
>> >>
>> >> El problema es el elevado número de tablas y sus correspondientes
>> >> campos
>> >> que no puedo, evidentemente cambiar a mano. Además existen objetos
>> >> dependientes, tales como vistas, índices, restricciones de
>> >> integridad
>> >> referencial y de clave primaria, procedimientos almacenados,
>> >> permisos
>> >> sobre tablas, etc...
>> >>
>> >> Así pues debo hacerlo automático. He pensado en crearme un script
>> >> de
>> >> generación de una base de datos completa y luego mediante un
>> >> "buscar y
>> >> reeemplazar", sustituir en el script todas las referencias a
>> >> nvarchar
>> >> a
>> >> varchar. Luego pasar el script sobre una base de datos de prueba y
>> >> pasar
>> >> los datos mediante un DTS de la original a la de prueba.
>> >>
>> >> ¿Es esto lo más correcto? ¿Existe alguna otra manera?
>> >>
>> >> Gracias anticipadas por todas vuestras respuestas.
>> >>
>> >
>> >
>>
>>
>>



Respuesta Responder a este mensaje
#7 José Manuel Blanes Pacheco
11/04/2006 - 21:32 | Informe spam
Gracias a los dos.

Lo cierto es que quizás las dos opciones sean posibles. Os cuento: como la
base de datos es de 20 gb y el servidor es lento, la opción de modificar las
columnas, vía las tablas de metadatos sea la más rápida, con la salvedad de
tener que crear los índices y restricciones (evidentemente mediante T-SQL).

No obstante, veo más sencilla la opción de Alejandro. Ya os contaré cuál de
las dos hago y los resultados.

Muchas gracias.

"DosFlores" escribió en el mensaje
news:%
Está claro, también se podrían leer los índices afectados y borrarlos para
luego volver a crearlos en el mismo script, aunque eso ya depende del
tiempo que se quiera emplear en la tarea de hacerlo.

Un saludo
Oscar Montesinos

"Alejandro Mesa" escribió en el
mensaje news:
Oscar,

Gracias por compartir el codigo con el grupo.

Fijate en este ejemplo donde se trata de alterar una columna que forma
parte
de la llave de un indice.

use northwind
go

create table t1(c1 nvarchar(15))
go

create nonclustered index t1_c1_nu_nc_idx
on t1(c1 asc)
go

alter table t1
alter column c1 varchar(15)
go

drop table t1
go

SQL Server reporta un error al tratar de hacer el "alter table".

Server: Msg 5074, Level 16, State 8, Line 2
The index 't1_c1_nu_nc_idx' is dependent on column 'c1'.
Server: Msg 4922, Level 16, State 1, Line 2
ALTER TABLE ALTER COLUMN c1 failed because one or more objects access
this
column.

Crear el script que mencionas, no es suficiente para cambiar todas la s
columnas nvarchar hacia varchar.


AMB


"DosFlores" wrote:

Prueba este generador de código T-SQL, si no entiendes algo me lo dices.

DECLARE @cmds AS VARCHAR(255)
DECLARE @cmdstr AS VARCHAR(255)

select @cmds = 'echo --Fichero de actualización > c:\Update.sql'
exec @cmdstr = master..xp_cmdshell @cmds

DECLARE @tabla AS VARCHAR(255)
DECLARE @columna AS VARCHAR(255)
DECLARE @longitud AS INT

DECLARE crs CURSOR FOR
SELECT so.name,sc.name,sc.length
FROM syscolumns AS sc INNER JOIN sysobjects AS so ON
sc.id=so.id AND
sc.xtype#1 AND so.xtype='U'
OPEN crs
FETCH NEXT FROM crs INTO @tabla,@columna,@longitud
WHILE (@@Fetch_Status=0)
BEGIN
NULL
select @cmds = 'echo ALTER TABLE '+@tabla+' >> c:\Update.sql'
exec @cmdstr = master..xp_cmdshell @cmds
select @cmds = 'echo ALTER COLUMN '+@columna+' >>
c:\Update.sql'
exec @cmdstr = master..xp_cmdshell @cmds
select @cmds = 'echo VARCHAR('+STR(@longitud)+') NOT NULL >>
c:\Update.sql'
exec @cmdstr = master..xp_cmdshell @cmds

FETCH NEXT FROM crs INTO @tabla,@columna,@longitud
END
CLOSE crs
DEALLOCATE crs

Un saludo
Oscar Montesinos

"Alejandro Mesa" escribió en
el
mensaje news:
> Pacheco,
>
> El problema grave aca es que no se puede alterar una columna que
> participa
> en un indice, restriccion, etc. Debes primero borrar el indice,
> restriccion,
> etc. Creo que la opcion primera por la que optastes es viable. Crea el
> script
> solo de las tablas, sin indices, llaves primarias, llaves foraneas,
> etc.
> (simplemente la estrutura de las tablas) y crea una nueva db. Antes de
> ejecutar el script, editalo con tu programa de preferencia y cambia
> todas
> las
> referencias de nchar/nvarchar/ntext por char/varchar/text y salvas el
> script.
> Ejecuta el script en la nueva db para crear las tablas y crea los
> paquetes
> dts necesarios para copiar la data. Luego creas un script para crear
> claves
> primarias, foraneas y cualquer otro tipo de restricciones y/o indices.
> Ejecutas el script en la db nueva despues de haber copiado la data.
>
> Sacas un backup de la db original y la eliminas. saca un backup de la
> nueva
> db nueva y la renombras con sp_renamedb. Si deseas cambiar los nombres
> logicos de los archivos de data y/o log, puedes usar "alter database".
> Si
> deseas cambiar los nombres fisicos de los archivos de data y/o log
> puedes
> sacar un backup y despues hacer un restore con la opcion "with move".
>
>
> AMB
>
> "José Manuel Blanes Pacheco" wrote:
>
>> Sería muy amable por tu parte que me lo pasaras para que me sirviera
>> de
>> guía.
>>
>> Muchas gracias.
>>
>>
>> "DosFlores" escribió en el mensaje
>> news:
>> > Puedes crear un script que te haga la modificación en todas las
>> > columnas.
>> >
>> > Se puede utilizar un cursor para:
>> >
>> > 1º Hacer un Select en syscolumns de todas las columnas unicode
>> > 2º Formas una cadena con la instrucción de modificación de la
>> > columna
>> > añadiendo el nombre de la columna y tabla a modificar.
>> > 3º Le añades ' >Fichero.sql' a la cadena formada con la instrucción
>> > 4º Insertas a un fichero la instrucción con con
>> > master.dbo.xp_cmdshell
>> > @tuInstruccion
>> >
>> > Tengo un script hecho por algún lado, si lo necesitas te lo puedo
>> > pasar.
>> >
>> > Un saludo
>> > Oscar Montesinos.
>> >
>> > "José Manuel Blanes Pacheco" escribió en el
>> > mensaje
>> > news:nIRZf.1829$
>> >> Hola grupo:
>> >>
>> >> Tengo una base en producción de 20 GB con casi cien tablas y todas
>> >> ellas
>> >> con muchas columnas de tipo nvarchar, nchar y ntext y ahora la
>> >> nueva
>> >> versión de la aplicación que la explota, una aplicación de GIS, no
>> >> puede
>> >> tratar con columnas de datos de tipo Unicode. Así que debo
>> >> pasarlas a
>> >> su
>> >> correspondiente tipo de datos con caracteres estandar.
>> >>
>> >> El problema es el elevado número de tablas y sus correspondientes
>> >> campos
>> >> que no puedo, evidentemente cambiar a mano. Además existen objetos
>> >> dependientes, tales como vistas, índices, restricciones de
>> >> integridad
>> >> referencial y de clave primaria, procedimientos almacenados,
>> >> permisos
>> >> sobre tablas, etc...
>> >>
>> >> Así pues debo hacerlo automático. He pensado en crearme un script
>> >> de
>> >> generación de una base de datos completa y luego mediante un
>> >> "buscar y
>> >> reeemplazar", sustituir en el script todas las referencias a
>> >> nvarchar
>> >> a
>> >> varchar. Luego pasar el script sobre una base de datos de prueba y
>> >> pasar
>> >> los datos mediante un DTS de la original a la de prueba.
>> >>
>> >> ¿Es esto lo más correcto? ¿Existe alguna otra manera?
>> >>
>> >> Gracias anticipadas por todas vuestras respuestas.
>> >>
>> >
>> >
>>
>>
>>









email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida