T-SQL Skalarfunktionen · Beispiele & Best Practices

🔢 T-SQL Skalarfunktionen · Praxisbeispiele

Einzelwert-Funktionen · Zeichenketten · Datum · Mathematik · Konvertierung · Logik
Skalarfunktionen verarbeiten einen einzelnen Wert und geben genau einen Wert zurück – einsetzbar überall dort, wo ein Ausdruck stehen kann.

Was sind Skalarfunktionen?

GRUNDLAGEN
Skalarfunktionen sind Funktionen, die einen einzelnen Wert (engl. "scalar") verarbeiten und genau einen Wert zurückgeben. Sie können überall dort verwendet werden, wo ein Ausdruck erlaubt ist – in SELECT, WHERE, ORDER BY, SET oder als DEFAULT-Wert. SQL Server bietet eine Vielzahl von integrierten Skalarfunktionen für unterschiedlichste Anforderungen.
-- Grundlegendes Beispiel: Skalarfunktionen im SELECT 
SELECT  
UPPER('hallo welt') AS Grossbuchstaben, 
GETDATE() AS AktuellesDatum, 
ROUND(123.456, 2) AS Gerundet;
💡 Erklärung: Im Beispiel werden drei verschiedene Skalarfunktionen aufgerufen: UPPER() wandelt einen String um, GETDATE() liefert den aktuellen Zeitstempel und ROUND() rundet eine Zahl. Jede Funktion gibt genau einen Wert zurück.

1. Zeichenketten-Funktionen (String Functions)

TEXT & ZEICHENKETTEN
Zeichenketten-Funktionen verarbeiten String-Eingaben und geben einen String oder eine numerische Position zurück. Sie sind unverzichtbar für Textbearbeitung, Formatierung und Extraktion von Teilstrings.
-- LEN: Länge eines Strings (ohne nachfolgende Leerzeichen) 
SELECT LEN('SQL Server') AS Laenge; -- Ergebnis: 10 
 
-- UPPER / LOWER: Groß- bzw. Kleinschreibung 
SELECT UPPER('sql') AS Gross, LOWER('WELT') AS Klein; -- 'SQL', 'welt' 
 
-- SUBSTRING: Teilstring extrahieren (ab Position 1, Länge 3) 
SELECT SUBSTRING('Datenbank', 1, 4) AS Teil; -- Ergebnis: 'Date' 
 
-- CHARINDEX: Position eines Teilstrings suchen 
SELECT CHARINDEX('Server', 'SQL Server 2022') AS Position; -- Ergebnis: 5 
 
-- REPLACE: Zeichen innerhalb eines Strings ersetzen 
SELECT REPLACE('Hallo Welt', 'Welt', 'SQL') AS Ersetzt; -- 'Hallo SQL' 
 
-- LTRIM + RTRIM: Führende und nachfolgende Leerzeichen entfernen 
SELECT LTRIM(RTRIM(' Text ')) AS Getrimmt; -- 'Text' 
 
-- CONCAT: Strings sicher verketten (behandelt NULL) 
SELECT CONCAT('Herr ', NULL, ' Maier') AS Name; -- 'Herr Maier'
📝 Erklärung: Die gängigsten String-Funktionen im Überblick: LEN() zählt Zeichen, UPPER()/LOWER() ändern die Groß-/Kleinschreibung, SUBSTRING() extrahiert Teile, CHARINDEX() sucht nach Positionen, REPLACE() ersetzt Text. CONCAT() ist besonders praktisch, da es NULL-Werte ignoriert.

2. Datums- und Zeitfunktionen

DATE & TIME
Datumsfunktionen sind essenziell für Zeitberechnungen, Altersbestimmungen und Berichtszeiträume. Sie ermöglichen das Extrahieren von Bestandteilen, das Addieren von Intervallen und die Differenzberechnung zwischen zwei Daten.
-- Aktuelles Datum und Uhrzeit 
SELECT  
GETDATE() AS AktuelleZeit, 
SYSDATETIME() AS HoheGenauigkeit, 
CURRENT_TIMESTAMP AS StandardZeit; 
 
-- DATEADD: Zeit zu einem Datum addieren (10 Tage in der Zukunft) 
SELECT DATEADD(DAY, 10, GETDATE()) AS In10Tagen; 
 
-- DATEDIFF: Differenz zwischen zwei Daten (in Tagen) 
SELECT DATEDIFF(DAY, '2024-01-01', GETDATE()) AS TageSeitNeujahr; 
 
-- DATEPART / YEAR / MONTH / DAY: Bestandteile extrahieren 
SELECT  
YEAR(GETDATE()) AS Jahr, 
MONTH(GETDATE()) AS Monat, 
DAY(GETDATE()) AS Tag; 
 
-- EOMONTH: Letzter Tag des aktuellen Monats 
SELECT EOMONTH(GETDATE()) AS Monatsende; 
 
-- FORMAT: Datum in benutzerdefiniertem Format (deutsch) 
SELECT FORMAT(GETDATE(), 'dd.MM.yyyy HH:mm', 'de-DE') AS DeutschFormat;
📅 Erklärung: GETDATE() liefert den aktuellen Zeitstempel. DATEADD() und DATEDIFF() sind die Arbeitstiere für Zeitberechnungen. YEAR(), MONTH() und DAY() sind Kurzformen von DATEPART(). Besonders praktisch: EOMONTH() für Monatsenden und FORMAT() für lokalisierte Datumsdarstellungen.

3. Konvertierungsfunktionen (CAST & CONVERT)

TYPUMWANDLUNG
Konvertierungsfunktionen wandeln einen Wert von einem Datentyp in einen anderen um. Sie sind unverzichtbar für typsichere Verarbeitung, Fehlervermeidung und korrekte Darstellung von Zahlen, Datumsangaben und Zeichenketten.
-- CAST: Standardkonvertierung zwischen zusammenhängenden Typen 
SELECT  
CAST(123.45 AS INT) AS Ganzzahl, 
CAST('2024-12-25' AS DATE) AS Weihnachten; 
 
-- CONVERT: Erweiterte Konvertierung mit Formatierungsoptionen (Style-Parameter) 
SELECT  
CONVERT(VARCHAR(10), GETDATE(), 104) AS Deutsch_Datum, -- dd.mm.yyyy 
CONVERT(VARCHAR(10), GETDATE(), 120) AS ISO_Datum; -- yyyy-mm-dd 
 
-- TRY_CAST / TRY_CONVERT: Fehlertolerante Umwandlung (gibt NULL statt Fehler) 
SELECT  
TRY_CAST('ABC' AS INT) AS Fehlerfrei, -- Ergebnis: NULL 
TRY_CONVERT(INT, '123') AS Erfolgreich; -- Ergebnis: 123 
 
-- Praktisches Beispiel: Sichere Umwandlung in Berichten 
SELECT  
ProduktCode, 
CASE  
WHEN TRY_CONVERT(INT, PreisText) IS NOT NULL  
THEN TRY_CONVERT(INT, PreisText) 
ELSE 0 
END AS PreisInteger 
FROM ProdukteImport;
🔄 Erklärung: CAST() ist die ANSI-Standardkonvertierung, CONVERT() bietet zusätzliche Formatierungsoptionen (z. B. Style 104 für deutsches Datum). Die TRY_*-Varianten sind besonders wertvoll: Sie verhindern Abbrüche bei ungültigen Konvertierungen, indem sie NULL zurückgeben statt einen Fehler auszulösen.
🚀 Best Practice: Verwenden Sie TRY_CAST/TRY_CONVERT anstelle von ISNUMERIC() mit anschließendem CAST. Die try-Funktionen sind sicherer, da sie echte Typkonvertierung durchführen, während ISNUMERIC() auch falsch-positive Ergebnisse liefern kann.

4. Mathematische Funktionen

ARITHMETIK & RUNDUNG
SQL Server bietet eine Vielzahl von mathematischen Funktionen für Berechnungen, Rundungen, Potenzen, Logarithmen und trigonometrische Operationen.
-- ABS: Absolutwert (entfernt Vorzeichen) 
SELECT ABS(-45.67) AS Absolut; -- 45.67 
 
-- CEILING / FLOOR: Auf-/Abrunden zur nächsten ganzen Zahl 
SELECT  
CEILING(12.34) AS Aufgerundet, -- 13 
FLOOR(12.98) AS Abgerundet; -- 12 
 
-- ROUND: Runden auf bestimmte Dezimalstellen 
SELECT  
ROUND(123.4567, 2) AS ZweiStellen, -- 123.46 
ROUND(123.4567, 0) AS Ganzzahl, -- 123.0 
ROUND(123.4567, -1) AS Zehner; -- 120 
 
-- POWER / SQUARE / SQRT: Potenzen und Wurzeln 
SELECT  
POWER(5, 3) AS Potenz, -- 125 (5³) 
SQUARE(9) AS Quadrat, -- 81 
SQRT(144) AS Wurzel; -- 12 
 
-- SIGN: Vorzeichen (-1 = negativ, 0 = null, +1 = positiv) 
SELECT  
SIGN(-42) AS Negativ, -- -1 
SIGN(0) AS Null. -- 0 
 
-- RAND: Zufallszahl zwischen 0 und 1 
SELECT RAND() AS Zufall, FLOOR(RAND() * 100) AS Zufall_1_bis_100;
🧮 Erklärung: Diese Funktionen decken den täglichen Bedarf ab: ROUND() rundet auf beliebige Nachkommastellen (auch negative Werte für Zehner-/Hunderterrundung). CEILING() und FLOOR() runden immer auf die nächste ganze Zahl. RAND() liefert eine Zufallszahl zwischen 0 und 1 – mit Multiplikation lassen sich beliebige Bereiche erzeugen.

5. Logische Funktionen (IIF, CHOOSE, COALESCE, NULLIF)

BEDINGUNGEN & NULL-BEHANDLUNG
Logische Funktionen vereinfachen bedingte Ausgaben und die Behandlung von NULL-Werten. Sie sind kompakte Alternativen zu komplexen CASE-Ausdrücken.
-- IIF: Bedingte Ausgabe (kurzform von CASE) 
SELECT  
Betrag, 
IIF(Betrag > 100, 'Hoch', 'Niedrig') AS Kategorie 
FROM Bestellungen; 
 
-- CHOOSE: Wert aus einer Liste anhand eines Index auswählen (ab 1 zählend) 
SELECT  
CHOOSE(2, 'Montag', 'Dienstag', 'Mittwoch') AS TagName; -- 'Dienstag' 
 
-- CHOOSE mit DATEPART (Monat → Quartal) 
SELECT  
Bestelldatum, 
CHOOSE(MONTH(Bestelldatum),  
'Winter','Winter','Frühling','Frühling', 
'Frühling','Sommer','Sommer','Sommer', 
'Herbst','Herbst','Herbst','Winter') AS Jahreszeit 
FROM Bestellungen; 
 
-- COALESCE: Ersten nicht-NULL-Wert in der Liste zurückgeben 
SELECT  
COALESCE(Handy, Telefon, 'Keine Rufnummer') AS Kontakt 
FROM Kunden; 
 
-- NULLIF: Gibt NULL zurück, wenn beide Argumente gleich sind 
SELECT  
Soll,  
Haben, 
NULLIF(Soll, Haben) AS Abweichung -- NULL wenn Soll = Haben, sonst Soll 
FROM Kontobewegungen;
⚖️ Erklärung: IIF() ist eine kompakte Schreibweise für IF-THEN-ELSE-Logik. CHOOSE() selektiert einen Wert aus einer Liste anhand eines Index – ideal für einfache Lookup-Tabellen direkt im Query. COALESCE() durchsucht eine Liste auf den ersten Nicht-NULL-Wert, NULLIF() gibt NULL zurück, wenn zwei Werte identisch sind. Zusammen sind sie perfekt für die NULL-Behandlung und Vermeidung von Divisionen durch Null.

6. Benutzerdefinierte Skalarfunktionen erstellen

UDF · EIGENE FUNKTIONEN
Mit benutzerdefinierten Skalarfunktionen (User-Defined Functions, UDFs) können Sie eigene, wiederverwendbare Logik kapseln – etwa für wiederkehrende Berechnungen oder Formatierungsaufgaben.
-- Einfache Skalarfunktion zum Berechnen des Bruttopreises 
CREATE FUNCTION dbo.fn_Bruttopreis(@Netto DECIMAL(10,2)) 
RETURNS DECIMAL(10,2) 
AS 
BEGIN 
DECLARE @Brutto DECIMAL(10,2); 
SET @Brutto = @Netto * 1.19; -- 19% Mehrwertsteuer 
RETURN @Brutto; 
END; 
GO 
 
-- Aufruf der benutzerdefinierten Funktion 
SELECT  
ProduktName, 
NettoPreis, 
dbo.fn_Bruttopreis(NettoPreis) AS BruttoPreis 
FROM Produkte; 
 
-- Löschen der Funktion, wenn nicht mehr benötigt 
-- DROP FUNCTION dbo.fn_Bruttopreis;
⚙️ Erklärung: Benutzerdefinierte Skalarfunktionen (UDFs) kapseln komplexe oder wiederkehrende Berechnungen. Im Beispiel wird eine MwSt.-Berechnung definiert. Die Funktion erhält einen Eingabeparameter (@Netto) und gibt einen einzelnen Wert (DECIMAL) zurück. Im BEGIN...END-Block wird die Logik implementiert, anschließend erfolgt die Rückgabe mit RETURN.
⚠️ Achtung bei UDFs: Klassische T-SQL Skalarfunktionen werden zeilenweise ausgeführt und können bei großen Datenmengen zu erheblichen Performance-Problemen führen. Für Set-Operationen bevorzugen Sie Alternativen wie Inline-Tabellenwertfunktionen oder lösen die Logik direkt im Query auf. Mit SQL Server 2019/2022 gibt es die "Scalar UDF Inlining"-Optimierung, die bestimmte UDFs automatisch in den Hauptquery einbettet.

Best Practices & Performance-Überlegungen

OPTIMIERUNG
Skalarfunktionen sind mächtige Werkzeuge, aber ihr Einsatz sollte wohlüberlegt sein. Die folgenden Tipps helfen Ihnen, sauberen und performanten Code zu schreiben.
-- 🚫 Schlecht: UDF in der WHERE-Klausel (führt zu zeilenweiser Ausführung) 
SELECT * FROM Kunden WHERE dbo.fn_KomplexePruefung(KundenID) = 1; 
 
-- ✅ Besser: Logik direkt in Set-basierter Operation umsetzen 
SELECT * FROM Kunden WHERE Status = 'Aktiv' AND Saldo > 0; 
 
-- ✅ Verwenden Sie UDFs primär dort, wo die Logik sonst extrem aufwendig oder die 
-- Datenmenge gering ist, z. B. in Berechnungen für einzelne Werte. 
 
-- Determinismus: Vermeiden Sie nicht-deterministische Funktionen in indizierten Sichten 
-- Nicht-deterministisch (kann sich bei jedem Aufruf ändern): 
-- GETDATE(), RAND(), NEWID() 
 
-- Determinisch (immer gleiche Ausgabe bei gleichem Input): 
-- UPPER(), LEN(), ROUND() mit Konstanten
💡 Performance-Faustregeln:
  • Vermeiden Sie UDFs in WHERE-Klauseln: Sie erzwingen oft eine zeilenweise Verarbeitung statt set-basierter Operationen und blockieren Index-Nutzung.
  • Prüfen Sie INLINING: Mit SQL Server 2019+ (Kompatibilitätslevel 150) und Azure SQL werden viele Skalar-UDFs automatisch inline eingebettet – das verbessert die Performance dramatisch.
  • Bevorzugen Sie Set-Operationen: Oft können Sie die Logik einer Skalarfunktion direkt in den Query als JOIN, CASE oder Fensterfunktion abbilden.
  • Nutzen Sie TRY_CAST/TRY_CONVERT für fehlertolerante Typumwandlungen – sie vermeiden Laufzeitfehler und ermöglichen saubere Fehlerbehandlung.

📌 Schnellreferenz: Wichtige Skalarfunktionen im Überblick

/* Zeichenketten */ LEN, UPPER/LOWER, CHARINDEX, PATINDEX, SUBSTRING, REPLACE, CONCAT, TRIM (ab 2017) 
/* Datum/Zeit */ GETDATE, DATEADD, DATEDIFF, YEAR/MONTH/DAY, DATEPART, EOMONTH, FORMAT 
/* Konvertierung */ CAST, CONVERT, TRY_CAST, TRY_CONVERT, PARSE, TRY_PARSE 
/* Mathematik */ ABS, ROUND, CEILING, FLOOR, POWER, SQRT, SQUARE, SIGN, RAND 
/* Logik / NULL */ IIF, CHOOSE, COALESCE, NULLIF, ISNULL 
/* Sicherheitsfunktionen */ USER_NAME, SESSION_USER, SUSER_SNAME, ORIGINAL_LOGIN 

Fazit: Skalarfunktionen sind unverzichtbare Helfer für flexible, lesbare SQL-Abfragen. Verwenden Sie die integrierten Funktionen, wo immer möglich – behalten Sie aber den Set-basierten Charakter von SQL im Hinterkopf. Für eigene UDFs gilt: Prüfen Sie die Performance und nutzen Sie modernes Inlining, wo verfügbar.