INSERT: agregar filas de forma explícita
Cuando registramos un cliente, un pedido o un movimiento de inventario necesitamos crear filas nuevas. INSERT indica la tabla de destino, las columnas que recibiremos y los valores que se almacenarán.
La lista explícita de columnas es importante: hace visible la intención y evita depender del orden físico de la tabla.
Sintaxis
INSERT INTO dbo.Tabla
(Columna1, Columna2, Columna3)
VALUES
(Valor1, Valor2, Valor3);
La correspondencia es posicional: Columna1 recibe Valor1, Columna2 recibe Valor2 y así sucesivamente. La cantidad de valores debe coincidir con la cantidad de columnas indicadas.
Ejemplo: insertar una fila
INSERT INTO dbo.Categoria (Nombre)
VALUES (N'Audio');
No incluimos IdCategoria porque es una columna IDENTITY: SQL Server genera automáticamente un número nuevo para cada fila. Tampoco necesitamos escribir todas las columnas cuando las omitidas aceptan NULL —un valor ausente o desconocido— o tienen un valor predeterminado definido por la tabla.
Insertar varias filas
Una sola instrucción puede contener varios grupos de valores:
INSERT INTO dbo.Categoria (Nombre)
VALUES
(N'Redes'),
(N'Impresión'),
(N'Energía');
Todas las filas deben proporcionar los valores en el mismo orden que la lista de columnas.
Insertar el resultado de una consulta
También podemos copiar o transformar datos provenientes de otro conjunto:
En el ejemplo, SUM reúne los importes de las partidas y GROUP BY produce una fila por pedido. El resultado de esa consulta debe tener la misma cantidad y el mismo orden de columnas que la lista del INSERT.
INSERT INTO dbo.PedidoHistorico
(IdPedidoOriginal, IdCliente, FechaPedido, Estado, Total)
SELECT
p.IdPedido,
p.IdCliente,
p.FechaPedido,
p.Estado,
SUM(pd.Cantidad * pd.PrecioUnitario * (1 - pd.Descuento / 100.0))
FROM dbo.Pedido AS p
INNER JOIN dbo.PedidoDetalle AS pd
ON pd.IdPedido = p.IdPedido
WHERE p.Estado IN ('Enviado', 'Cancelado')
GROUP BY
p.IdPedido,
p.IdCliente,
p.FechaPedido,
p.Estado;
Conviene ejecutar primero únicamente la consulta para comprobar qué filas insertará.
Confirmar lo insertado
OUTPUT permite recuperar valores generados y filas afectadas sin realizar una búsqueda posterior:
INSERT INTO dbo.Categoria (Nombre)
OUTPUT inserted.IdCategoria, inserted.Nombre
VALUES (N'Seguridad');
Para capturar un único identificador IDENTITY también existe SCOPE_IDENTITY(), que devuelve el último valor generado dentro del mismo alcance de ejecución. OUTPUT devuelve datos de las filas afectadas y resulta más flexible cuando la instrucción inserta varias filas.
Qué conviene comprobar
Antes de insertar revisamos restricciones, tipos, longitudes y duplicados. Una restricción es una regla que la tabla hace cumplir. UNIQUE impide valores repetidos; una llave foránea exige una fila relacionada y CHECK valida una condición escrita en la definición.
Cuando la operación involucra varias tablas relacionadas, una transacción agrupa los cambios para confirmarlos o revertirlos como una unidad. Así evitamos conservar solo una parte. También debemos decidir qué debería ocurrir si ejecutamos el mismo proceso dos veces: insertar duplicados, actualizar lo existente o ignorar filas ya procesadas.