Zum Inhalt springen

Typumwandlung

Typumwandlung (Casting) bezeichnet die Umwandlung eines Werts eines bestimmten Datentyps in den entsprechenden Wert eines anderen Datentyps. Die Umwandlung kann implizit oder explizit erfolgen. Die hier beschriebene Syntax führt eine explizite Umwandlung durch. Weitere Informationen zur Typumwandlung finden Sie auf der Seite Typumwandlung.

Explizite Typumwandlung

Die Standard-SQL-Syntax für explizite Typumwandlung ist CAST(expr AS TYPENAME), wobei TYPENAME ein Name (oder Alias) eines der DuckDB-Datentypen ist. DuckDB unterstützt außerdem die Kurzform expr::TYPENAME, die auch in PostgreSQL vorhanden ist.

SELECT CAST(i AS VARCHAR) AS i
FROM generate_series(1, 3) tbl(i);
i
1
2
3
SELECT i::DOUBLE AS i
FROM generate_series(1, 3) tbl(i);
i
1.0
2.0
3.0

Regeln zur Typumwandlung

Nicht alle Umwandlungen sind möglich. Beispielsweise lässt sich ein INTEGER nicht in ein DATE umwandeln. Umwandlungen können auch Fehler werfen, wenn sie nicht erfolgreich durchgeführt werden konnten. Der Versuch, die Zeichenkette 'hello' in ein INTEGER umzuwandeln, führt beispielsweise zu einem Fehler.

SELECT CAST('hello' AS INTEGER);
Terminal window
Conversion Error:
Could not convert string 'hello' to INT32

Das genaue Verhalten der Umwandlung hängt von Quell- und Zieltyp ab. Beim Umwandeln von VARCHAR in einen anderen Typ wird beispielsweise versucht, die Zeichenkette zu konvertieren.

Die Umwandlung zwischen numerischen Typen kann Rundungsfolgen haben. Die geltenden Rundungsregeln finden Sie auf der Seite zum Typ NUMERIC.

TRY_CAST

TRY_CAST kann verwendet werden, wenn das bevorzugte Verhalten nicht das Werfen eines Fehlers ist, sondern die Rückgabe von NULL. TRY_CAST wirft nie einen Fehler und gibt stattdessen NULL zurück, wenn eine Umwandlung nicht möglich ist.

SELECT TRY_CAST('hello' AS INTEGER) AS i;
i
NULL

Funktion cast_to_type

Die Funktion cast_to_type erzeugt eine Typumwandlung von einem Ausdruck in den Typ einer anderen Spalte. Zum Beispiel:

SELECT cast_to_type('42', NULL::INTEGER) AS result;
┌───────┐
│ res │
│ int32 │
├───────┤
│ 42 │
└───────┘

Diese Funktion ist vor allem in Makros nützlich, weil sie Typen beibehält. So lassen sich generische Makros schreiben, die auf verschiedenen Typen arbeiten. Das folgende Makro addiert beispielsweise zu einer Zahl, wenn die Eingabe ein INTEGER ist:

CREATE TABLE tbl (i INT, s VARCHAR);
INSERT INTO tbl VALUES (42, 'hello world');
CREATE MACRO conditional_add(col, nr) AS
CASE
WHEN typeof(col) == 'INTEGER' THEN cast_to_type(col::INTEGER + nr, col)
ELSE col
END;
SELECT conditional_add(COLUMNS(*), 100) FROM tbl;
┌───────┬─────────────┐
│ i │ s │
│ int32 │ varchar │
├───────┼─────────────┤
│ 142 │ hello world │
└───────┴─────────────┘

Beachten Sie, dass die CASE-Anweisung in allen Zweigen denselben Typ zurückgeben muss. Wir können die Addition auf jeder Eingabespalte durchführen, indem wir in den gewünschten Typ umwandeln – das Ergebnis der Addition müssen wir aber wieder in den Quelltyp umwandeln, damit die Bindung funktioniert.