In SQL kun je bedrijfslogica implementeren via gebruikers gedefinieerde functies (User Defined Functions, UDF), wat toestaat om een deel van de berekeningen en bedrijfsregels naar de database te verplaatsen.
Schaalbare functies retourneren een enkel waarde en worden in expressies aangeroepen — bijvoorbeeld om een totale prijs te berekenen op basis van parameters:
CREATE FUNCTION dbo.GetDiscount(@price DECIMAL(10,2), @loyaltyLevel INT) RETURNS DECIMAL(10,2) AS BEGIN RETURN @price * CASE WHEN @loyaltyLevel = 1 THEN 0.95 WHEN @loyaltyLevel = 2 THEN 0.90 ELSE 1.0 END END; -- Voorbeeld van gebruik: SELECT Name, dbo.GetDiscount(Price, LoyaltyLevel) AS DiscountPrice FROM Products;
Tabelvormige functies retourneren een set rijen (een tabel):
CREATE FUNCTION dbo.ActiveOrders(@userId INT) RETURNS TABLE AS RETURN ( SELECT * FROM Orders WHERE UserId = @userId AND Status = 'Active' ); -- Gebruik: SELECT * FROM dbo.ActiveOrders(123);
Verschillen, beperkingen en aanbevelingen:
Wat is het verschil tussen een INLINE tabelvormige functie en een multi-statement tabelvormige functie? Hoe beïnvloedt deze keuze de prestaties?
Antwoord en voorbeeld:
-- INLINE CREATE FUNCTION dbo.InlineActiveOrders(@userId INT) RETURNS TABLE AS RETURN ( SELECT * FROM Orders WHERE UserId = @userId AND Status = 'Active' ); -- Multi-statement CREATE FUNCTION dbo.MultiActiveOrders(@userId INT) RETURNS @result TABLE (...) AS BEGIN INSERT INTO @result SELECT ... -- logica RETURN END
Geschiedenis
Project: Financiële analyse.
We gebruikten schaalbare UDF in de select-gedeelte van een rapportagequery naar een grote hoeveelheid tabellen: SELECT Amount, dbo.CalcTax(Amount, Type) FROM Transactions. De query duurde 5-10 minuten vanwege rij-voor-rij verwerking van de UDF. We herschreven het naar ingebouwde CASE: de tijd daalde tot seconden.
Geschiedenis
Project: E-commerce. Voor het vinden van gebruikerswagentjes gebruikten we multi-statement tabelvormige functies, waar logica van filtering in meerdere stappen was. Het bleek dat SQL geen optimaal plan opbouwde en een scan uitvoerde, zelfs wanneer maar één element nodig was. Vervangen door een INLINE-functie versnelde de queries onmiddellijk met 50 keer.
Geschiedenis
Project: CRM. We verplaatsten de bedrijfslogica voor het toekennen van bonussen naar een complexe UDF. Na een paar maanden realiseerden we ons dat de formules van het bedrijf waren veranderd, en het bijwerken van de functie was moeilijk vanwege de strikte koppeling met de gegevens. In een iteratief product leidde de UDF tot hoge kosten voor coördinatie van wijzigingen tussen de backend en de database.