ProgrammatieBackend ontwikkelaar

Hoe implementeer je complexe bedrijfsregels en berekeningen direct in SQL met behulp van gebruikers gedefinieerde functies (User Defined Functions, UDF)? Wat zijn de verschillen en beperkingen tussen schaalbare en tabelvormige UDF, wanneer zijn ze nuttig en wanneer is het beter om dergelijke logica in een externe applicatie te implementeren?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

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:

  • Schaalbare UDF hebben vaak een lage prestaties bij grote datasets, omdat ze per rij worden aangeroepen;
  • Tabelvormige UDF worden beter geïntegreerd in query-plannen en kunnen worden gebruikt als gewone tabellen;
  • Logica die toegang tot externe bronnen of complexe bedrijfsverwerkingen vereisen, is beter buiten SQL te plaatsen.

Lastige vraag.

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-functie (single-statement, retourneert direct een SELECT) wordt geoptimaliseerd als onderdeel van de hoofdquery, creëert geen extra tabel en werkt sneller, het query-plan is gezamenlijk.
  • Multi-statement functie creëert een tijdelijke tabel (tabelvariabele), waardoor het query-plan vaak slechter is, beoordelingsfouten van cardinaliteit mogelijk zijn en de prestaties afnemen.
-- 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.