In SQL kann man Geschäftslogik durch benutzerdefinierte Funktionen (User Defined Functions, UDF) realisieren, wodurch ein Teil der Berechnungen und Geschäftsregeln in die Datenbank verlagert wird.
Skalare Funktionen geben einen einzelnen Wert zurück und werden in Ausdrücken aufgerufen — zum Beispiel, um einen Gesamtbetrag basierend auf Parametern zu berechnen:
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; -- Beispielverwendung: SELECT Name, dbo.GetDiscount(Price, LoyaltyLevel) AS DiscountPrice FROM Products;
Tabellarische Funktionen geben eine Menge von Zeilen (Tabelle) zurück:
CREATE FUNCTION dbo.ActiveOrders(@userId INT) RETURNS TABLE AS RETURN ( SELECT * FROM Orders WHERE UserId = @userId AND Status = 'Active' ); -- Verwendung: SELECT * FROM dbo.ActiveOrders(123);
Unterschiede, Einschränkungen und Empfehlungen:
Was ist der Unterschied zwischen einer INLINE tabellarischen Funktion und einer mehrstufigen (multi-statement) tabellarischen Funktion? Wie beeinflusst diese Wahl die Leistung?
Antwort und Beispiel:
-- INLINE CREATE FUNCTION dbo.InlineActiveOrders(@userId INT) RETURNS TABLE AS RETURN ( SELECT * FROM Orders WHERE UserId = @userId AND Status = 'Active' ); -- Mehrstufige CREATE FUNCTION dbo.MultiActiveOrders(@userId INT) RETURNS @result TABLE (...) AS BEGIN INSERT INTO @result SELECT ... -- Logik RETURN END
Geschichte
Projekt: Finanzanalyse.
Wir verwendeten skalare UDFs im SELECT-Teil eines Berichts über eine große Datenmenge: SELECT Amount, dbo.CalcTax(Amount, Type) FROM Transactions. Die Abfrage dauerte 5-10 Minuten aufgrund der zeilenweisen Verarbeitung der UDF. Wir schrieben es auf eingebautes CASE um: die Zeit reduzierte sich auf Sekunden.
Geschichte
Projekt: E-Commerce. Zur Suche nach Benutzerwarenkörben verwendeten wir mehrstufige tabellarische Funktionen, bei denen die Filterlogik in mehreren Schritten auftrat. Es stellte sich heraus, dass SQL keinen optimalen Plan erstellt und Scans durchführt, selbst wenn nur ein Element benötigt wird. Der Ersatz durch eine INLINE-Funktion beschleunigte die Abfragen sofort um das 50-Fache.
Geschichte
Projekt: CRM. Wir verlagerten die Geschäftslogik zur Gewährung von Boni in eine komplexe UDF. Nach ein paar Monaten stellten wir fest, dass sich die Geschäftsformeln geändert hatten, und es schwierig war, die Funktion zu aktualisieren, da sie eng mit den Daten verbunden war. In einem iterativen Produkt führte die UDF zu hohen Kosten für die Koordination von Änderungen zwischen Backend und DB.