SQL ServerTVVideos
436
0

CUIDADO al usar TRIGGERS

Los Triggers o también llamados desencadenadores son un objeto de programación en SQL Server y otros motores de bases de datos los cuales permiten escribir código SQL y que esto se dispara para las operaciones INSERT/UPDATE y DELETE.

Ahora bien, el usarlos tiene sus consecuencias y en este video te voy a explicar cuales son y que cuidados debes tener para evitar problemas de rendimiento en tu base de datos.

Código usado en el video

SQL
use AdventureWorks2019
go

drop table if exists YourBigTable
-- Paso 1: Crear una tabla similar a Sales.SalesOrderDetail con 2 millones de registros ficticios
CREATE TABLE YourBigTable (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    ProductID bigINT,
    OrderQty bigINT,
    UnitPrice MONEY
    -- Agrega más columnas según sea necesario
);

-- Paso 2: Insertar 2 millones de registros ficticios
INSERT INTO YourBigTable (ProductID, OrderQty, UnitPrice)
SELECT top 5000000
    ABS(CHECKSUM(NEWID())) % 1000 + 1, -- ProductID aleatorio entre 1 y 1000
    ABS(CHECKSUM(NEWID())) % 10 + 1,    -- OrderQty aleatorio entre 1 y 10
    RAND() * 1000                       -- UnitPrice aleatorio entre 0 y 1000
FROM
    sys.all_columns a
CROSS JOIN
    sys.all_columns b;

-- Verificar que se hayan insertado los registros
SELECT COUNT(*) FROM YourBigTable;

CREATE OR ALTER PROC DBO.USP_YourBigTable_UPDATE @cant int = 50
AS
 UPDATE top (@cant)
 YourBigTable
 SET OrderQty = OrderQty *1,
     unitprice = UnitPrice * 1
 WHERE ID > 1 and 
 id <= convert(int,RAND() * 1000)
GO

-- creamos un simple trigger
SELECT * FROM SYS.triggers 
WHERE parent_id = OBJECT_ID('YourBigTable')

CREATE TRIGGER DEMO1 ON YourBigTable FOR  INSERT AS
 ROLLBACK TRAN
GO

-- DEMO INSERT
INSERT INTO YourBigTable (ProductID, OrderQty, UnitPrice)
SELECT 
ABS(CHECKSUM(NEWID())) % 1000 + 1, -- ProductID aleatorio entre 1 y 1000
ABS(CHECKSUM(NEWID())) % 10 + 1,    -- OrderQty aleatorio entre 1 y 10
RAND() * 1000                       -- UnitPrice aleatorio entre 0 y 1000

-- DROP TRIGGER
DROP TRIGGER DEMO1

-- INSERTAMOS DE NUEVO
INSERT INTO YourBigTable (ProductID, OrderQty, UnitPrice)
SELECT 
ABS(CHECKSUM(NEWID())) % 1000 + 1, -- ProductID aleatorio entre 1 y 1000
ABS(CHECKSUM(NEWID())) % 10 + 1,    -- OrderQty aleatorio entre 1 y 10
RAND() * 1000                       -- UnitPrice aleatorio entre 0 y 1000

---- demo tiempos Y TRIGGERS

DROP TABLE IF EXISTS dbo.product

SELECT * INTO DBO.PRODUCT
FROM Production.Product  

-- CREAMOS UN TRIGGER PARA
DROP TRIGGER IF EXISTS DEMOTRB

CREATE OR ALTER TRIGGER DEMOTRB ON DBO.PRODUCT
FOR UPDATE
as
BEGIN
 UPDATE DBO.PRODUCT SET COLOR='N/A'
 WAITFOR DELAY '00:00:59'
END



ALTER TABLE DBO.PRODUCT DISABLE TRIGGER ALL

UPDATE DBO.PRODUCT SET COLOR = COLOR

ALTER TABLE DBO.PRODUCT ENABLE TRIGGER ALL

BEGIN TRAN
 UPDATE DBO.PRODUCT SET COLOR = 'RED'
ROLLBACK TRAN

-- EN OTRA VENTANA

EXEC SP_WHOISACTIVE

DBCC OPENTRAN
 
SELECT * FROM DBO.PRODUCT 



---- CREAMOS UN TRIGGER con logica y malas Practicas 


DROP TABLE IF EXISTS CloneYourBigTable

SELECT * 
INTO CloneYourBigTable
FROM YourBigTable

CREATE INDEX CI ON CloneYourBigTable(ID)
CREATE INDEX CI1 ON CloneYourBigTable(PRODUCTID,
									  OrderQty,
                                      UnitPrice
									  )
-- CREAMOS UN TRIGGER MAS COMPLEJO
DROP TRIGGER IF EXISTS trg_ComplexTrigger ;

CREATE OR ALTER TRIGGER trg_ComplexTrigger
ON YourBigTable
AFTER INSERT, UPDATE
AS
BEGIN
    SET NOCOUNT ON
	-- Ejemplo de lógica más compleja usando un cursor
    DECLARE @ID INT,
	        @PRODUCTID BIGINT,
			@ORDERQTY BIGINT,
			@UNITPRICE MONEY

    DECLARE cur CURSOR FOR
    SELECT ID,ProductID,OrderQty,UnitPrice 
	FROM inserted;

    OPEN cur;
    FETCH NEXT FROM cur INTO @ID,@PRODUCTID,@ORDERQTY,@UNITPRICE;

    WHILE @@FETCH_STATUS = 0
    BEGIN
        
		UPDATE CloneYourBigTable
		SET OrderQty = @ORDERQTY,
		    ProductID = @PRODUCTID,
			UnitPrice = @UNITPRICE
		WHERE ID=@ID

        FETCH NEXT FROM cur INTO @ID,@PRODUCTID,@ORDERQTY,@UNITPRICE;
    END;

    CLOSE cur;
    DEALLOCATE cur;
END;

-- PROBAR
-- PRUEBA DE STRESS 50 HILOS 50 ITETACIONES


ALTER TABLE YourBigTable DISABLE TRIGGER ALL

SET STATISTICS TIME ON

EXEC DBO.USP_YourBigTable_UPDATE

ALTER TABLE YourBigTable enable TRIGGER ALL

You must be logged in to post a comment.