📖 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)
- Inline (iTVF): Najbrže. SQL Server ih tretira kao parametrizovane upite (parameterized views).
- Multi-statement (MSTVF): Sličnije proceduri, imaju svoje tabele i logiku. SQL Server često pogrešno procijeni broj redova koje vraćaju, što dovodi do loših planova izvršenja.
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.
-- 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:
- ✅ Uvijek preferirajte Inline TVF nad bilo kojim drugim tipom.
- ✅ Iskoristite UDF Inlining u SQL Server 2022 za brze skalarne izračune.
- ✅ Izbjegavajte pristupe bazi unutar funkcija ako planirate raditi sa velikim datasetovima.
📚 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).