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);

Ejemplo: insertar una fila

INSERT INTO dbo.Categoria (Nombre)
VALUES (N'Audio');

No incluimos IdCategoria porque es una columna IDENTITY; SQL Server genera su valor. Tampoco necesitamos escribir todas las columnas de una tabla cuando las omitidas aceptan NULL o tienen un valor predeterminado.

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:

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;

La cantidad y el orden de las columnas producidas por SELECT deben corresponder con el destino. 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(). OUTPUT 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 UNIQUE, una llave foránea o una validación CHECK puede rechazar una fila que no cumple el modelo.

Cuando la operación involucra varias tablas relacionadas, una transacción evita conservar solo una parte del cambio. 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.

Relacionado con

  • SELECT: puede producir las filas que serán insertadas.
  • Transacciones y TRY/CATCH: agrupan modificaciones que deben completarse juntas.
  • OUTPUT, inserted y deleted: devuelven las filas afectadas.
  • Restricciones: determinan qué datos puede aceptar la tabla.