Ein Datum aus einer CSV-Datei landet als Text in der Datenbank — und plötzlich wird aus dem 2. November der 11. Februar. Solche stillen Fehlinterpretationen sind der Klassiker bei der Typ-Konvertierung in SQL Server. Wer CAST, CONVERT, TRY_CAST und TRY_CONVERT samt Style-Parameter kennt, vermeidet sie.
Das Wichtigste vorab:
CASTist ANSI-SQL-Standard und portabel.CONVERT(undTRY_CONVERT) sind SQL-Server-spezifisch.TRY_CASTundTRY_CONVERTliefern bei einem nicht konvertierbaren WertNULLstatt eines Konvertierungsfehlers und eignen sich damit für fehlertolerante ETL-Prüfungen.- Der Style-Parameter (nur bei
CONVERT/TRY_CONVERT) steuert das Format der Konvertierung — etwa, wie ein Text-Datum interpretiert wird. - Im ETL gilt: Eingangsformate (Datum, Zahl, Ja/Nein, NULL) vorab festlegen.
Voraussetzung: SQL Server mit SSMS. Die Beispiele sind reines T-SQL ohne Sample-Datenbank.
Dieser Artikel gehört zur Serie Datenqualität in einem ETL-Prozess, in der ein Design Pattern vorgestellt wird, das die extrahierten Daten prüft, behandelt und schlechte Daten von der weiteren Verarbeitung ausschließt.
Welche Funktion wann? Die folgende Merkhilfe ordnet die vier Funktionen nach Einsatzzweck:
| Aufgabe | Funktion |
|---|---|
| Standard-Konvertierung, portabel | CAST |
| Format explizit über Style steuern | CONVERT |
Fehlertolerant (NULL statt Fehler) | TRY_CAST |
| Fehlertolerant und Style-gesteuert | TRY_CONVERT |
CAST, CONVERT, TRY_CAST und TRY_CONVERT — der Überblick
SQL Server bietet mit CAST, CONVERT, TRY_CAST und TRY_CONVERT vier Funktionen zur Typ-Konvertierung. Die Syntax von CAST und TRY_CAST bzw. CONVERT und TRY_CONVERT ist jeweils identisch. Der Unterschied liegt im Fehlerverhalten: Schlägt eine zulässige Konvertierung fehl (etwa weil der Text kein gültiges Datum enthält), liefern TRY_CAST und TRY_CONVERT NULL statt eines Konvertierungsfehlers. Eine explizit nicht erlaubte Konvertierung wie TRY_CAST(4 AS xml) führt dagegen auch bei den TRY_-Varianten weiterhin zu einem Fehler.
Die beiden folgenden Abschnitte leiten die zwei zentralen Unterschiede zwischen den Funktions-Paaren im Detail her: die Portabilität und den Style-Parameter.
Unterschied 1: ANSI-SQL vs. SQL-Server-spezifisch
Zum einen ist CONVERT (und damit auch TRY_CONVERT) SQL-Server-spezifisch und entspricht nicht dem ANSI-SQL-Standard. Anders ausgedrückt: CAST gehört zum ANSI-SQL-Standard und wird deshalb von den verbreiteten relationalen Datenbanksystemen unterstützt, etwa von Oracle und Postgres. Welche Konvertierungen im Einzelnen zulässig sind, unterscheidet sich jedoch je nach Hersteller. Ein CONVERT mit äquivalenter Funktionsweise gibt es dort meist nicht. Auch TRY_CAST gehört nicht zum ANSI-SQL-Standard — SQL Server hat es eingeführt, einige andere Systeme bieten inzwischen aber ebenfalls eine TRY_CAST-Variante.
Unterschied 2: der Style-Parameter
Zum anderen besitzen CONVERT und TRY_CONVERT einen Style-Parameter, den CAST und TRY_CAST nicht haben. Er steuert abhängig von den beteiligten Datentypen das Format der Konvertierung: Bei Text-zu-Datum legt er fest, wie die Eingabe gelesen wird, bei Datum-zu-Text bestimmt er das Ausgabeformat (auch für float– und money-Konvertierungen gibt es Style-Codes). Der wichtigste Anwendungsfall ist ein Datum, das als Text an die Funktionen CAST oder CONVERT übergeben wird. Das Datum 02.11.2024 (deutsche Schreibweise) wird je nach Land ganz unterschiedlich notiert. SQL Server spricht diese Schreibweisen über Style-Codes an:
| Land | Formatstring | Datum | Style-Parameter |
|---|---|---|---|
| Deutschland | dd.mm.yyyy | 02.11.2024 | 104 |
| USA | mm-dd-yyyy | 11-02-2024 | 110 |
| Japan | yyyy/mm/dd | 2024/11/02 | 111 |
Bei solchen mehrdeutigen, sprachabhängigen Schreibweisen muss das Eingangsformat eindeutig bekannt sein und explizit berücksichtigt werden — über den passenden Style-Parameter oder ein von vornherein eindeutiges Eingangsformat. Die folgenden SELECT-Statements verdeutlichen die Problematik:
1: SET DATEFORMAT mdy;
2:
3: SELECT CAST('02.11.2024' AS date); -- 2024-02-11
4: SELECT CAST('11-02-2024' AS date); -- 2024-11-02
5: SELECT CAST('2024/11/02' AS date); -- 2024-11-02
6:
7: SELECT CONVERT(date, '02.11.2024', 104); -- 2024-11-02
8: SELECT CONVERT(date, '2024/11/02', 111); -- 2024-11-02
9: SELECT CONVERT(date, '11-02-2024', 110); -- 2024-11-02
10:
11: SELECT CONVERT(date, '02.11.2024', 111);
12: -- Fehler: Conversion failed when converting date and/or
13: -- time from character string.
Die hinter den Kommentarzeichen notierten Werte stammen aus dem Resultset im SQL Server Management Studio. SSMS stellt einen date-Wert in der Ergebnisansicht standardmäßig im ISO-Format yyyy-MM-dd dar — das ist die Anzeigeform des Clients, nicht das Speicherformat des Datentyps.
Wichtig: Wie CAST ein Text-Datum interpretiert, hängt von der DATEFORMAT– bzw. LANGUAGE-Einstellung der Session ab. Zeile 1 setzt das Datumsformat deshalb explizit auf mdy, den Default einer Standard-Installation mit us_english — so bleiben die Ergebnisse unabhängig von Server-Konfiguration und Login reproduzierbar. Unter dieser Einstellung interpretiert CAST das deutsche Datum in Zeile 3 falsch: statt 02.11.2024 steht 11.02.2024 im Ergebnis (unter dmy käme das korrekte 02.11.2024 heraus, bei anderen Werten auch ein Konvertierungsfehler). Genau deshalb sollte man sich bei einem Text-Datum nie auf die implizite Interpretation verlassen: Mit dem korrekten Style-Parameter 104 in Zeile 7 liest CONVERT ein deutsches Datum dagegen zuverlässig.
Wo sich das Eingangsformat festlegen lässt, ist ein eindeutiges Format die robusteste Wahl: CAST('20241102' AS date) liefert unabhängig von LANGUAGE und DATEFORMAT den 2. November 2024. Das ungetrennte Format yyyymmdd empfiehlt auch Microsoft als sprachneutrale Schreibweise für Datums-Literale.
Was das für ETL bedeutet
Für ETL-Prozesse ergeben sich daraus zwei Konsequenzen:
- Eine sichere Typ-Konvertierung ist oft schwieriger, als sie auf den ersten Blick wirkt. Das gilt übrigens auch für vermeintlich einfache Datentypen wie
decimalundfloat. - Bei ETL-Prozessen, die Daten aus Dateien übernehmen (CSV, XML, JSON, …), muss genau festgelegt sein, in welchem Format ein Datum, eine Zahl, eine Ja/Nein-Information, ein
NULLund anderes geliefert werden.
Die Folge-Serie Datenqualität // Sichere Typ-Konvertierung mit T-SQL verwendet (fast) ausschließlich die Funktion TRY_CONVERT für die Typ-Konvertierung. Grund hierfür ist die Möglichkeit der Angabe eines Style-Parameters, über den sich die Interpretation des Eingangswertes steuern lässt. Ein NULL-Ergebnis ist dabei nur dann ein Fehler-Signal, wenn der Eingangswert selbst nicht NULL war — die Folge-Serie speichert deshalb Eingangs- und Ausgangswert getrennt und identifiziert Konvertierungsfehler über deren Vergleich.
Wer die hier vorgestellte Systematik der Typ-Konvertierung auf ein anderes Datenbank-System übertragen möchte, muss dort äquivalente Funktionen finden oder gegebenenfalls eigene Hilfsfunktionen schreiben. Die geringere Portabilität durch die SQL-Server-spezifische Funktion ist dabei ein bewusster Kompromiss. Bei Verwendung der Funktion CAST würde zusätzlicher Entwicklungsaufwand entstehen und gegebenenfalls die Les- und Wartbarkeit der erforderlichen T-SQL-Artefakte beeinträchtigen.
In Postgres: CAST ja, TRY_CONVERT nein
Wer dieselbe Logik in Postgres braucht, findet einen Teil davon wieder — aber nicht alles. CAST ist auch in Postgres ANSI-Standard und besitzt dieselbe Syntax. Die dort übliche Kurzform wert::typ ist dagegen Postgres-spezifisch. Welche Konvertierungen im Einzelnen zulässig sind, kann sich je nach System aber unterscheiden. Einen direkten Ersatz für CONVERT mit Style-Parameter oder für TRY_CONVERT / TRY_CAST gibt es jedoch nicht:
- Datums- und Zahlenformate lassen sich über
to_date(text, format)bzw.to_number(text, format)mit expliziter Formatmaske steuern, z. B.to_date('02.11.2024', 'DD.MM.YYYY'). - Eine fehlertolerante Konvertierung, die statt eines Fehlers
NULLliefert, muss nachgebaut werden. Üblich ist eine kleine PL/pgSQL-Hilfsfunktion mitBEGIN … EXCEPTION … END;, die den Konvertierungsfehler gezielt über seine Fehlerklasse abfängt undNULLzurückgibt (ein pauschalesWHEN othersfängt auch unbeabsichtigte Fehler mit), oder eine Vorab-Prüfung des Eingangswerts — dabei hilft ab Postgres 16 die eingebaute Validierungs-Funktionpg_input_is_valid(text, typ).
Die Grundregel bleibt dieselbe: Eingangsformat kennen, Konvertierung absichern. Nur das Werkzeug heißt anders.
Zusammenfassung
- Für die Standard-Konvertierung ohne Format-Steuerung ist
CASTdie richtige Wahl: Die Funktion ist ANSI-SQL und damit die portabelste der vier. Welche Konvertierungen zulässig sind, bleibt allerdings system-abhängig. - Sobald das Eingangsformat eine Rolle spielt (etwa ein Text-Datum in lokaler Schreibweise), gehört der Style-Parameter dazu — also
CONVERToder fehlertolerantTRY_CONVERT. - Im ETL empfiehlt sich
TRY_CONVERT: Eingangsformate vorab festlegen undNULL-Ergebnisse auswerten, statt den Lauf mit einem Laufzeitfehler abbrechen zu lassen. Als Fehler-Signal zählt einNULLdabei nur, wenn der Eingangswert selbst nichtNULLwar.
FAQ
CAST oder CONVERT — was soll ich nehmen? CAST ist ANSI-SQL, portabel und die erste Wahl, wenn keine Format-Steuerung nötig ist. CONVERT ist immer dann nötig, wenn der Style-Parameter steuern soll, wie ein Text (besonders ein Datum) interpretiert wird. Im ETL-Kontext führt deshalb meist kein Weg an CONVERT bzw. TRY_CONVERT vorbei.
TRY_CONVERT ein NULL statt einer Fehlermeldung zurück? Genau das ist der Zweck: Schlägt eine zulässige Konvertierung fehl, liefern TRY_CONVERT und TRY_CAST NULL, statt die Verarbeitung mit einem Fehler abzubrechen. So lassen sich in einem ETL-Lauf schlechte Datensätze erkennen und gezielt aussteuern, statt dass der ganze Batch abbricht.
TRY_CAST oder TRY_CONVERT — was ist der Unterschied? Das Fehlerverhalten ist identisch: Beide liefern bei einer fehlgeschlagenen zulässigen Konvertierung NULL. TRY_CONVERT bietet zusätzlich den Style-Parameter, der bei Datums- und Geld-Konvertierungen relevant ist. Wer nah am portablen CAST-Stil bleiben will, nimmt TRY_CAST. Wer das Eingangsformat steuern muss, braucht TRY_CONVERT.
Der Style-Parameter (drittes Argument von CONVERT / TRY_CONVERT) legt fest, nach welchem Schema ein Text interpretiert wird, etwa 104 für das deutsche Datumsformat dd.mm.yyyy. Ohne passenden Style interpretiert SQL Server ein Text-Datum abhängig von der LANGUAGE– bzw. DATEFORMAT-Einstellung der Session und liefert damit leicht ein falsches Ergebnis (siehe Zeile 3 im Beispiel oben).
02.11.2024 in SQL Server? Mit dem Style-Parameter 104: TRY_CONVERT(date, '02.11.2024', 104) liefert den 2. November 2024 — unabhängig von den Sprach-Einstellungen der Session. Bei einem ungültigen Wert gibt TRY_CONVERT NULL zurück, während CONVERT stattdessen mit einem Fehler abbricht.
Teilweise — siehe Abschnitt „In Postgres“. CAST ja, CONVERT / TRY_CONVERT nein. Die Format-Steuerung läuft dort über to_date / to_number, eine fehlertolerante Konvertierung über eine eigene Hilfsfunktion.
Verwandte Artikel
- Serie (Hub): Datenqualität in einem ETL-Prozess
- Das Design Pattern: Sichere Typ-Konvertierung mit T-SQL
- TRY_CONVERT pro Datentyp: date, datetime, datetime2, time · decimal, numeric · bigint, int, smallint, tinyint · money, smallmoney · float, real · bit