MODUL 3 - LEKCIJA 4

Odgovor na promjene podataka putem Trigera

Automatizacija poslovnih pravila, auditing i magic tables duboki uvid

⏱️ Trajanje: ~3 časa 📚 Nivo: Srednji do Napredni 🎯 Praktični primjeri: 6

📖 Šta su Trigeri (Okidači)?

Triger je posebna vrsta stored procedure koja se izvršava automatski kao odgovor na određeni događaj (event). To može biti promjena podataka (DML), promjena strukture (DDL) ili prijava korisnika na server. Trigeri su "nevidljiva ruka" baze koja garantuje da se određena pravila izvrše bez obzira na to koji dio aplikacije šalje SQL kod.

✨ Magic Tables: Inserted i Deleted

Kada se triger pokrene, SQL Server kreira dvije privremene, memorijske tabele koje postoje samo unutar scope-a trigera:

🚫 Najveća zabluda o trigerima

Mnogi vjeruju da se triger pokreće za svaki red posebno. OVO JE NETAČNO. Triger se pokreće jednom po SQL naredbi (npr. ako uradite update 1000 redova, triger leti JEDNOM, a tabela inserted će imati 1000 redova). Kod trigera MORATE pisati set-based kod.

⚡ DML Trigeri: AFTER vs INSTEAD OF

1. AFTER Trigeri

Izvršavaju se nakon što je SQL operacija (i sve constraint provjere) uspješno završena. Idealni za Auditing (zapisivanje ko je šta promijenio).

2. INSTEAD OF Trigeri

Presreću operaciju i izvršavaju umjesto nje. Najčešće se koriste na Complex Views kako bi omogućili unos podataka u tabele koje su spojene u pogledu.

🛠️ Primjer Auditing Trigera (Automatsko praćenje)
CREATE TRIGGER trg_AuditBudgetChanges
ON Stats.Projects
AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;
    
    -- Bilježimo promjenu samo ako je kolona 'Budget' stvarno promijenjena
    IF UPDATE(Budget)
    BEGIN
        INSERT INTO Audit.BudgetLog (ProjectID, OldBudget, NewBudget, ChangedDate, ChangedBy)
        SELECT i.ProjectID, d.Budget, i.Budget, GETDATE(), SYSTEM_USER
        FROM inserted i
        JOIN deleted d ON i.ProjectID = d.ProjectID
        WHERE i.Budget <> d.Budget; -- Ignorišemo "fake" updejte
    END
END;
GO

🛡️ DDL Trigeri: Zaštita strukture

Želite spriječiti da bilo ko obriše (DROP) tabelu u produkciji? DDL trigeri su rješenje.

🚫 Stop 'DROP TABLE'
CREATE TRIGGER trg_PreventDropTable
ON DATABASE
FOR DROP_TABLE
AS
BEGIN
   PRINT 'Nije dozvoljeno brisanje tabela u ovoj bazi podataka!';
   ROLLBACK; -- Poništava DROP komandu
END;

🎯 Praktična Vježba: Pametna Validacija

Zadatak: Zaštita od masovne katastrofe

Vaša agencija želi spriječiti da bilo ko obriše više od 10 izvještaja odjednom (kako bi se spriječili "accidental" deletions miliona redova).

💡 Rješenje
CREATE TRIGGER trg_SafeDeleteReports
ON Stats.Reports
AFTER DELETE
AS
BEGIN
    DECLARE @Count INT = (SELECT COUNT(*) FROM deleted);
    
    IF @Count > 10
    BEGIN
        RAISERROR('Brisanje više od 10 izvještaja odjednom je zabranjeno iz sigurnosnih razloga.', 16, 1);
        ROLLBACK TRANSACTION;
    END
END;
GO

⚙️ Performanse i Opasnosti

✅ Zaključak

Trigeri su moćan, ali opasan alat:

📚 Sljedeća Lekcija

U Lekciji 3.5 prelazimo na najnapredniji dio programabilnosti: CLR Integration. Naučićete kako izvršiti .NET kod (C#) direktno unutar SQL Servera za stvari koje T-SQL jednostavno ne može uraditi.