Diario de SQL Server

Mover datos de tablas con identities

 

Supongamos un escenario en el que se tienen varias tablas relacionadas, donde la clave primaria de esas tablas es un identity, que aparece luego como foreign key en la tabla relacionada, que también a su vez está en otra tercera tabla, incluso que existen tablas que cuentan con dos o tres de esos campos, originalmente identity todos ellos. En estos escenarios, igualar los datos de un entorno a otro puede resultar un poco complicado si ambos entornos han evolucionado de forma paralela.

El ejemplo, sería el de una aplicación que lleva en producción un tiempo, con sus altas, eliminaciones de registros, y pasado ese tiempo, es necesario volcar registros adicionales, de varias tablas, todas relacionadas. El problema está en que los identificadores que hay que pasar ya existen en el entorno de destino. Y al usarse esos identity como foreign key en otras tablas, la alternativa a la que puede estar uno abocado es a realizar ese traspaso de datos de forma manual, permitiendo que se vayan asignando los identificadores en las tablas, para luego usarlos en las relacionadas. Si hay que pasar miles de registros, hacerlo a mano es inviable.

Existen tres alternativas adicionales (al menos). Una pasa por preparar un conjunto de procedimientos almacenados que nos ayuden en la tarea. Es la opción más ordenada, pero también puede suponer un esfuerzo importante si no se cuenta ya previamente con dichos procedimientos (usados en la propia aplicación para el mantenimiento de esas tablas). La segunda sería construir tablas de traducción o equivalencias entre identificadores. Esta vía, si hay una o dos tablas es fácil, pero si hay más, puede ser bastante tortuoso.

La otra forma, que es la que quiero exponer, consiste en generar un salto fijo en los identity de todas las tablas implicadas, por ejemplo, sumándole 10000 a los valores de todos los identity de los que partimos inicialmente.

El objetivo de esto es poder mantener las relaciones entre los valores del entorno de origen y llevarlos al de destino, de forma ordenada y contando con que puedo seguir relacionándolos, mediante una sencilla suma (o resta) de 10.000.

Cómo haríamos esto.

TablaMaestro: IdMaestro, Descripcion, FechaAlta

TablaDetalle: IdDetalle, IdMaestro, Descripcion

TablaDesglose: IdDesglose, IdDetalle, Descripcion

 

set identity_insert TablaMaestro on

insert TablaMaestro (IdMaestro, Descripcion, FechaAlta)

select IdMaestro = IdMaestro + 10000, Descripcion, FechaAlta

from [DESARROLLO].MiBD..TablaMaestro

where FechaAlta > '20110901' --> Estos son los datos a pasar, los dados de alta desde que se separaron los entornos, y todos los relacionados

set identity_insert TablaMaestro off

 

set identity_insert TablaDetalle on

insert TablaDetalle (IdDetalle, IdMaestro, Descripcion)

select IdDetalle = IdDetalle + 10000, IdMaestro = IdMaestro + 10000, Descripcion

from [DESARROLLO].MiBD..TablaDetalle

where IdMaestro in (Select IdMaestro from [DESARROLLO].MiBD..TablaMaestro where FechaAlta > '20110901')

set identity_insert TablaDetalle off

 

set identity_insert TablaDesglose on

insert TablaDesglose (IdDesglose, IdDetalle, Descripcion)

select IdDesglose = IdDesglose + 10000, IdDetalle = IdDetalle + 10000, Descripcion

from [DESARROLLO].MiBD..TablaDesglose

where IdDetalle in (select IdDetalle from [DESARROLLO].MiBD..TablaDetalle where IdMaestro in (Select IdMaestro from [DESARROLLO].MiBD..TablaMaestro where FechaAlta > '20110901'))

set identity_insert TablaDesglose off

 

 

Y así con todas las tablas que se debieran subir. Luego, si procede, hay que recolocar el valor por el que crece el identity, con DBCC CHECKIDENT.

 

 

Comentarios

No hay ningún comentario

Añadir un Comentario: