Uso práctico de MERGE en procedimientos almacenados SQL
Resumen
¿Cómo utilizar el comando MERGE de forma práctica en SQL?
El comando MERGE en SQL se ha convertido en una herramienta valiosa para simplificar operaciones complejas de bases de datos. Permite realizar operaciones como actualizaciones, inserciones o eliminaciones de datos en una sola sentencia. En esta clase, exploraremos cómo implementar MERGE como un procedimiento almacenado, pasando valores por parámetros sin usar una tabla fuente.
¿Cómo crear un procedimiento almacenado utilizando MERGE?
Un procedimiento almacenado es una secuencia predefinida de comandos SQL que puede ser ejecutada por un llamado. Este enfoque puede ser sumamente práctico para gestionar operaciones recurrentes sobre datos. En este ejemplo, utilizaremos la base de datos Platzi y nos enfocaremos únicamente en la tabla target.
Definir parámetros: Primero, debemos crear tres parámetros que correspondan con las columnas de nuestra tabla target, por ejemplo: codigo, nombre y puntos.
Sintaxis básica de MERGE: La estructura del comando MERGE comenzará de la siguiente manera:
MERGEINTO target AS T
USING(VALUES(@codigo,@nombre,@puntos))AS S (codigo, nombre, puntos)ON T.codigo = S.codigo
WHENMATCHEDTHENUPDATESET T.nombre = S.nombre, T.puntos = S.puntos
WHENNOTMATCHEDTHENINSERT(codigo, nombre, puntos)VALUES(S.codigo, S.nombre, S.puntos);
Particularidades del ejemplo: En este caso, si un registro existe (WHEN MATCHED), se actualizará. Si no existe (WHEN NOT MATCHED), se insertará un nuevo registro.
¿Qué pruebas realizar para entender mejor MERGE?
Probar el procedimiento almacenado con diferentes conjuntos de datos y observar el comportamiento del MERGE es crucial para comprender su funcionamiento.
Ejecutar el procedimiento con datos existentes: Si introduces un registro ya presente en la tabla target pero con un nuevo valor para la columna puntos, el MERGE realizará una actualización en lugar de una inserción.
Añadir un nuevo registro: Prueba con un registro completamente nuevo. Observa cómo el MERGE inserta este nuevo registro en la tabla target.
¿Dónde encontrar ejemplos para practicar?
En el archivo adjunto con este curso, encontrarás un ejemplo modificado de la práctica oficial de SQL que puedes utilizar con la base de datos Adventure Works 2019. Aquí puedes:
Manipular consultas y procesos almacenados: Esto te permitirá experimentar con MERGE en un contexto más complejo, mejorando tus habilidades y confianza en el uso de este comando.
Recuerda que practicar estas lecciones con diferentes conjuntos de datos y condiciones te ayudará a afinar tus habilidades en SQL y te permitirá utilizar comandos como MERGE con mayor eficacia en entornos reales y más complejos de producción. ¡Continúa aprendiendo y experimentando!
Como dato a los que les interese, para que no le salgan tantos subrayados en rojo en el script (y esto pasa porque SQL no reconoce que una columna, una tabla, procedimiento, vista y otros, existe o se ha creado), es porque toca actualizar la caché local del SQL. Lo pueden hacer en en menú Editar > IntelliSense > Actualizar caché local. O pueden presionar las teclas Ctrl + Mayus. + R
Super
Gracias
Tambien se puede utilizar Table Type para enviar directamente la cantidad que se necesite de registros a actualizar con el Merge, siguiendo el ejemplo mostrado seria solo sustituir algunas lineas de codigosL
CREATE TABLE UsuarioTarget
(
Codigo INTEGER,
Nombre VARCHAR(100),
Puntos INTEGER
);
CREATE TYPE TEST AS TABLE
(
Codigo INTEGER,
Nombre VARCHAR(100),
Puntos INTEGER
);
DECLARE @TEST TEST;
INSERT INTO @TEST VALUES(1, 'DAVID', 100), (2, 'JUAN', 60);
SELECT * FROM @TEST
SELECT * FROM UsuarioTarget;
EXEC MerceUsuarioTarget @TEST
SELECT * FROM UsuarioTarget;
CREATE PROCEDURE MerceUsuarioTarget
@TEST TEST READONLY
AS
BEGIN
MERGE UsuarioTarget AS T
USING @TEST AS S
ON (T.Codigo = S.Codigo)
WHEN MATCHED THEN
UPDATE SET T.Nombre = S.Nombre,
T.Puntos = S.Puntos
WHEN NOT MATCHED THEN
INSERT (Codigo, Nombre, Puntos)
VALUES (S.Codigo, S.Nombre, S.Puntos) ;
END
Utilizando Table Type se puede enviar mas información hacia el SP creado, me funciona cuando tengo que enviar gran cantidad de información en una sola conexion, para no realizar una conexion por cada registro de una Tabla.
Llevo 3 años trabajando con SQL y confirmo que siempre hay cosas por aprender. Está super super bueno este curso 💚
Estoy de acuerdo
Investigando un poco sobre los MERGE y sus uso, encontré un blog referente al autor del curso que explica estos ejemplos:
Merge en SQL
Todo muy claro en el post que compartes, nada que ver con la explicación realizada por el profesor en estos videos :/
Salvo la redacción, varios errores de ortografía.
También creo que podría realizarse así, dandole el alias dentro del select en el using
En cuestiones de rendimiento, veo que se verifica el dato que ingreso en la variable @codigo y lo compara con el campo Codigo de la tabla.
Esa comparación qué tan optima es ?
¿Qué diferencia hay en hacer un merge como en el ejemplo y un poco más de sql como IF EXISTS(SELECT * FROM UsuarioTarget WHERE Codigo = @codigo) ?
Si haces como lo indices con el if vas a hacer mas consultas a la base de datos, y en cambio MERGE por su naturaleza hace todo mucho mas eficiente.
Una PROCEDURE (procedimiento almacenado) es un conjunto de instrucciones SQL que se almacenan en la base de datos y se pueden ejecutar como una unidad. Se utilizan para realizar tareas específicas, como insertar, actualizar o eliminar datos, y pueden recibir parámetros para personalizar su ejecución.
El profesor usa procedimientos almacenados para encapsular la lógica de negocio y simplificar las consultas. Esto mejora la eficiencia, permite reutilizar código y facilita el mantenimiento, lo que es clave en la optimización de consultas SQL.
El uso de procedimientos almacenados (stored procedures) en SQL depende del contexto y los requerimientos de la aplicación:
Uso de procedimientos:
Cuando necesitas encapsular lógica compleja o varias operaciones que se ejecutan juntas.
Para mejorar el rendimiento, ya que se compilan y optimizan en el servidor.
Cuando quieres mantener la seguridad, limitando el acceso directo a las tablas.
No usar procedimientos:
Para tareas simples que no justifican la sobrecarga de un procedimiento.
Cuando la lógica puede ser fácilmente manejada en la capa de aplicación.
Elige según la necesidad específica de tu proyecto.
Realmente imposible continuar el curso con este profesor. Hasta luego.
En que momento se creo la Db Platzi?
Al parecer la clase 11 no existe o el vídeo está dañado, también me encontré con ese problema.
Si me pasa exactamente lo mismo si alguno tiene la base de datos PLATZI por favor compartirla, Mil gracias!!!!
SE PUEDE USAR ASI?
USING (SELECT @codigo CODIGO,@nombre NOMBRE,@puntos PUNTOS) AS S
O SE RECOMIENDA ASI:
USING (SELECT @codigo,@nombre,@puntos) AS S
(Codigo, Nombre, Puntos)
?
Funciona de las dos formas. Yo prefiero hacerlo como lo explico ya que a mi me parece más ordenado, pero de las dos formas funciona.
Si van a borrar un sp antes tratar de buscar si existe con la siguiente sentencia (y también manejar sps con _ no con . Porque es más difícil a la hora de buscarlos)
<code>Borrar el sp si ya existe
IFEXISTS(SELECT*FROM sys.objectsWHERE type ='P'ANDOBJECT_ID=OBJECT_ID('dbo.Production_msp_UpdateInventory'))DROPPROCEDUREProduction_msp_UpdateInventoryGO
El comando MERGE en SQL permite realizar operaciones de actualización y eliminación, pero no acepta condiciones como un WHERE directamente. Sin embargo, puedes incluir una condición dentro de la cláusula ON para especificar qué filas comparar. Por ejemplo, puedes usar una comparación de fechas en esa cláusula para que solo se afecten registros que cumplan con esa condición. Así, el MERGE se ejecutará solo en los registros que correspondan a la fecha que deseas.
Entendido
Toco cambiar el nombre del procedimiento, para que no saque error Production.msp_UpdateInventory :
Una manera de verificar si un Procedure existe, y en la parte final de la practica el SP invocado no concuerda con el SP creado.
USE AdventureWorks2019
BEGIN TRANSACTION
ROLLBACK
IF (OBJECT_ID('sp_ActualizaInventario') IS NOT NULL)
DROP PROCEDURE sp_ActualizaInventario
GO
SELECT * FROM Production.ProductInventory WHERE ProductID = 707
go
CREATE OR ALTER PROCEDURE msp_ActualizaInventario
@OrderDate datetime
AS
MERGE Production.ProductInventory AS target
USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod
JOIN Sales.SalesOrderHeader AS soh
ON sod.SalesOrderID = soh.SalesOrderID
AND soh.OrderDate = @OrderDate
GROUP BY ProductID) AS source (ProductID, OrderQty)
ON (target.ProductID = source.ProductID)
WHEN MATCHED AND target.Quantity - source.OrderQty <= 0
THEN DELETE
WHEN MATCHED
THEN UPDATE SET target.Quantity = target.Quantity - source.OrderQty,
target.ModifiedDate = GETDATE()
OUTPUT $action,source.ProductID, source.OrderQty,
Inserted.ProductID, Inserted.Quantity,
Inserted.ModifiedDate, Deleted.ProductID,
Deleted.Quantity, Deleted.ModifiedDate;
GO
select * from Production.ProductInventory WHERE ProductID = 707
select * from Production.ProductInventory WHERE ProductID = 747