🔢 T-SQL Skalarfunktionen · Praxisbeispiele
Was sind Skalarfunktionen?
GRUNDLAGEN-- Grundlegendes Beispiel: Skalarfunktionen im SELECT
SELECT
UPPER('hallo welt') AS Grossbuchstaben,
GETDATE() AS AktuellesDatum,
ROUND(123.456, 2) AS Gerundet;
1. Zeichenketten-Funktionen (String Functions)
TEXT & ZEICHENKETTEN-- 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'
2. Datums- und Zeitfunktionen
DATE & TIME-- 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;
3. Konvertierungsfunktionen (CAST & CONVERT)
TYPUMWANDLUNG-- 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;
4. Mathematische Funktionen
ARITHMETIK & RUNDUNG-- 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;
5. Logische Funktionen (IIF, CHOOSE, COALESCE, NULLIF)
BEDINGUNGEN & NULL-BEHANDLUNG-- 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;
6. Benutzerdefinierte Skalarfunktionen erstellen
UDF · EIGENE FUNKTIONEN-- 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;
Best Practices & Performance-Überlegungen
OPTIMIERUNG-- 🚫 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
- 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.