SQL: Inserciones Anidadas con Autonuméricos

[forTips] SQL Server

Probablemente, alguna vez hayáis tenido que crear un script SQL para crear datos en una tabla; hasta aquí todo sencillo. Pero como la mayoría de situaciones, la vida del informático no es fácil; y nos encontraremos que nos piden insertar datos en una tabla, y a su vez otros datos en una tabla que depende de la primera.

Para visualizarlo un poco y hacerlo fácil de entender, partiremos de un ejemplo básico con el que se ilustrarán un par de ideas fácilmente reutilizables.

insert-batch-output

 

Como veis es un ejemplo de tablas muy, pero que muy simple. En el ejemplo insertaremos una serie de personas, y una mascota para cada una de ellas.

Paso a paso

Primero de todo creamos una tabla temporal en memoria, donde almacenaremos los datos de las personas que serán insertadas, con el Id asignado automáticamente por SQL Server.

DECLARE @Temp TABLE
(
	Id int,
	Nombre varchar(50)
);

Como primer paso, realizamos una inserción batch en la tabla Personas. Para quienes no conozcan las inserciones batch, decir que consiste en realizar la típica pareja INSERT INTO-VALUES en una sola transacción  de datos, ahorrando tiempo internamente en la inserción del log de SQL Server. O lo que es lo mismo, en una instrucción insertar varias filas.

INSERT INTO Personas(Nombre)
OUTPUT inserted.Id, inserted.Nombre
INTO @Temp
VALUES('Juan'),('Pedro'),('Jaime'),('Carlos');
¿Os habéis dado cuenta?

Pasamos a explicar que pinta la instrucción OUTPUT e INTO en medio de un insert, y como logramos el objetivo. Lo único que indicamos, es que los datos que se insertan en la tabla Personas, también se inserten en la tabla temporal (pueden ser todas las filas como en el ejemplo, o un subconjunto de ellas).

Como nota, decir que existe la variable inserted donde tendremos los datos de la fila insertada.

Esto nos evita tener que deshabilitar el IDENTITY  de la tabla, crear los datos con un Id en la tabla temporal, realizar los cambios, y volver a habilitarlo. Evitamos errores y posibles descuidos.

Finalmente, la última parte del script sería algo tan sencillo como usar los datos de la tabla temporal de Personas para insertar nuestras mascotas.

INSERT INTO Mascotas(Nombre, PersonaId)
SELECT 'Mascota de ' + Nombre, Id
FROM @Temp;

Links

Para más información sobre los temas tratadas, os dejo unos links que os pueden ayudar como guía. Además de un script demo, que crea las tablas y realiza lo que hemos comentado en una transacción que no llega a persistirse; para que tengáis el ejemplo completo, y podáis usarlo como base si es necesario.