🔢 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.