🔢 T-SQL Skalarfunktionen · Praxisbeispiele
Einzelwert-Funktionen · Zeichenketten · Datum · Mathematik · Konvertierung · Logik
Inhalt
Was sind Skalarfunktionen?
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)
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
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)
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
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)
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
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
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.