MODUL 3 - LEKCIJA 3

Korisnički Definisane Funkcije (UDF)

Ekspertski vodič kroz skalarno i tabelarno programiranje uz izbjegavanje skrivenih usporavanja

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

📖 Izračuni unutar Upita

User-Defined Functions (UDF) vam omogućavaju da enkapsulirate logiku koja vraća vrijednost izravno unutar SELECT ili WHERE klauzule. Iako izgledaju nevino, funkcije u bazi su često najveći neprijatelj performansi ako se ne koriste pažljivo.

🧩 Tipovi Funkcija

1. Scalar UDF (Skalarne funkcije)

Vraćaju jednu vrijednost (npr. string, broj). Decenijama su bile spore jer se izvršavaju red po red (RBAR - Row By Agonizing Row), čime onemogućavaju paralelizam.

🚀 Revolucija: UDF Inlining

Od SQL Servera 2019, engine može automatski "ubaciti" (inline) kod skalarne funkcije u upit. Ovo transformiše sporu funkciju u brzi izraz sličan CASE iskazu, ali samo ako funkcija zadovoljava set strogih pravila (isključeni kursor, privremene tabele, itd.).

2. Table-Valued Functions (Tabelarne funkcije)

🛠️ Zlatni standard: Inline TVF
CREATE FUNCTION Stats.itvf_GetEmployeeReports (@EmpID INT)
RETURNS TABLE
AS
RETURN (
    -- Samo JEDNA SELECT naredba bez dodatnog koda
    SELECT ReportID, ReportName, CreatedDate, Status, ReportType
    FROM Stats.Reports
    WHERE CreatedBy = @EmpID
);
GO

-- Korištenje (cross apply je vaš najbolji prijatelj ovdje)
SELECT e.FirstName + ' ' + e.LastName AS EmployeeName, r.ReportName, r.CreatedDate
FROM Stats.Employees e
CROSS APPLY Stats.itvf_GetEmployeeReports(e.EmployeeID) r;

⚖️ Determinizam: Mogu li indeksirati funkciju?

Funkcija je deterministička ako za iste ulazne podatke UVIJEK vraća isti rezultat (npr. SQUARE(x)). Funkcija kao GETDATE() je nedeterministička.

⚡ Zašto je ovo važno?

Samo determinističke funkcije možete koristiti unutar Persisted Computed Columns ili Indexed Views. Ako funkcija dotiče bazu (čak i samo čita), SQL Server je smatra nedeterminističkom po defaultu.

🎯 Praktična Vježba: Popravljanje sporih upita

Zadatak: Konverzija MSTVF u iTVF

Dobili ste kod koji koristi Multi-statement funkciju za formatiranje adresa. Upit nad milion redova traje 30 sekundi.

Loš pristup (MSTVF): Funkcija koja deklarira @table varijablu i radi INSERT pa RETURN.

💡 Brzo Rješenje (iTVF)
-- Umjesto kompleksne logike, sve pakujemo u jedan izraz
CREATE OR ALTER FUNCTION dbo.itvf_FormatAddress (@Street NVARCHAR(100), @City NVARCHAR(50))
RETURNS TABLE 
AS
RETURN (
    SELECT FormattedAddress = UPPER(@Street) + ', ' + UPPER(@City)
);
GO

-- Performanse: Ovaj pristup omogućava SQL Serveru da "vidi" kroz funkciju i koristi indekse na Street/City kolonama.

✅ Zaključak

Funkcije su alat za čitljivost, ali performanse su prioritet:

📚 Sljedeća Lekcija

U Lekciji 3.4 istražujemo Trigere. Naučićete kako automatski reagovati na izmjene podataka (INSERT/UPDATE/DELETE) i kako koristiti Magic Tables (Inserted i Deleted).