- Amazon Relational Database Service

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Il type casting in PostgreSQL è il processo di conversione di un valore da un tipo di dati a un altro. PostgreSQL fornisce cast integrati per molte conversioni comuni, ma puoi anche creare cast personalizzati per definire come devono comportarsi le conversioni di tipi specifici.

Un cast specifica come eseguire una conversione da un tipo di dati a un altro. Ad esempio, la conversione di testo '123' in numero intero 123 o di numeri 45.67 in testo. '45.67'

Per informazioni complete sui concetti e sulla sintassi del casting di PostgreSQL, consulta la documentazione PostgreSQL CREATE CAST.

A partire dalle per installare cast aggiuntivi per tipi integrati, pur potendo creare cast personalizzati tipi.

Installazione e utilizzo dell'estensione rds_casts

Per creare l'rds_castsestensione, connettiti all' ed esegui il comando seguente: rds_superuser

CREATE EXTENSION IF NOT EXISTS rds_casts;

Cast supportati

Crea l'estensione in ogni database in cui desideri utilizzare i cast personalizzati. Dopo aver creato l'estensione, utilizzate il seguente comando per visualizzare tutti i cast disponibili:

SELECT * FROM rds_casts.list_supported_casts();

Questa funzione elenca le combinazioni di cast disponibili (tipo di origine, tipo di destinazione, contesto di coercizione e funzione di cast). Ad esempio, se vuoi text crearlo numeric come cast. implicit Puoi usare la seguente query per scoprire se il cast è disponibile per la creazione:

SELECT * FROM rds_casts.list_supported_casts() WHERE source_type = 'text' AND target_type = 'numeric'; id | source_type | target_type | qualified_function | coercion_context ----+-------------+-------------+--------------------------------------+------------------ 10 | text | numeric | rds_casts.rds_text_to_numeric_custom | implicit 11 | text | numeric | rds_casts.rds_text_to_numeric_custom | assignment 13 | text | numeric | rds_casts.rds_text_to_numeric_custom | explicit 20 | text | numeric | rds_casts.rds_text_to_numeric_inout | implicit 21 | text | numeric | rds_casts.rds_text_to_numeric_inout | assignment 23 | text | numeric | rds_casts.rds_text_to_numeric_inout | explicit

L'estensione rds_casts fornisce due tipi di funzioni di conversione per ogni cast:

  • funzioni _inout: utilizzano il meccanismo di I/O conversione standard di PostgreSQL, che si comporta in modo identico ai cast creati con il metodo INOUT

  • _custom functions: forniscono una logica di conversione avanzata che gestisce i casi limite, come la conversione di stringhe vuote in valori NULL per evitare errori di conversione

Le inout funzioni replicano il comportamento di casting nativo di PostgreSQL, mentre custom le funzioni estendono questa funzionalità gestendo scenari che i cast INOUT standard non sono in grado di supportare, come la conversione di stringhe vuote in numeri interi.

Creare o eliminare cast

Puoi creare e eliminare i cast supportati utilizzando due metodi:

Creazione di cast

Metodo 1: utilizzo del comando CREATE CAST nativo

CREATE CAST (text AS numeric) WITH FUNCTION rds_casts.rds_text_to_numeric_custom AS IMPLICIT;

Metodo 2: utilizzo della funzione rds_casts.create_cast

SELECT rds_casts.create_cast(10);

La funzione prende l'ID dall'output. create_cast list_supported_casts() Questo metodo è più semplice e garantisce l'utilizzo della combinazione corretta di funzione e contesto. È garantito che questo id rimanga lo stesso tra le diverse versioni di postgres.

Per verificare che il cast sia stato creato correttamente, interroga il catalogo del sistema pg_cast:

SELECT oid, castsource::regtype, casttarget::regtype, castfunc::regproc, castcontext, castmethod FROM pg_cast WHERE castsource = 'text'::regtype AND casttarget = 'numeric'::regtype; oid | castsource | casttarget | castfunc | castcontext | castmethod --------+------------+------------+--------------------------------------+-------------+------------ 356372 | text | numeric | rds_casts.rds_text_to_numeric_custom | i | f

La castcontext colonna mostra: e per EXPLICIT, per ASSIGNMENT o a per IMPLICIT. i

Eliminare i calchi

Metodo 1: utilizzo del comando DROP CAST

DROP CAST IF EXISTS (text AS numeric);

Metodo 2: utilizzo della funzione rds_casts.drop_cast

SELECT rds_casts.drop_cast(10);

La drop_cast funzione accetta lo stesso ID utilizzato durante la creazione del cast. Questo metodo assicura che tu stia eliminando il cast esatto creato con l'ID corrispondente.

Creazione di cast personalizzati con una strategia contestuale adeguata

Quando si creano più cast per tipi interi, possono verificarsi errori di ambiguità dell'operatore se tutti i cast vengono creati come IMPLICITI. L'esempio seguente dimostra questo problema creando due cast impliciti dal testo a diverse larghezze di numeri interi:

-- Creating multiple IMPLICIT casts causes ambiguity postgres=> CREATE CAST (text AS int4) WITH FUNCTION rds_casts.rds_text_to_int4_custom(text) AS IMPLICIT; CREATE CAST postgres=> CREATE CAST (text AS int8) WITH FUNCTION rds_casts.rds_text_to_int8_custom(text) AS IMPLICIT; CREATE CAST postgres=> CREATE TABLE test_cast(col int); CREATE TABLE postgres=> INSERT INTO test_cast VALUES ('123'::text); INSERT 0 1 postgres=> SELECT * FROM test_cast WHERE col='123'::text; ERROR: operator is not unique: integer = text LINE 1: SELECT * FROM test_cast WHERE col='123'::text; ^ HINT: Could not choose a best candidate operator. You might need to add explicit type casts.

L'errore si verifica perché PostgreSQL non è in grado di determinare quale cast implicito utilizzare quando si confronta una colonna intera con un valore di testo. Entrambi i cast impliciti int4 e int8 sono candidati validi, il che crea ambiguità.

Per evitare questa ambiguità dell'operatore, usa il contesto ASSIGNMENT per larghezze intere più piccole e il contesto IMPLICIT per larghezze intere più grandi:

-- Use ASSIGNMENT for smaller integer widths CREATE CAST (text AS int2) WITH FUNCTION rds_casts.rds_text_to_int2_custom(text) AS ASSIGNMENT; CREATE CAST (text AS int4) WITH FUNCTION rds_casts.rds_text_to_int4_custom(text) AS ASSIGNMENT; -- Use IMPLICIT for larger integer widths CREATE CAST (text AS int8) WITH FUNCTION rds_casts.rds_text_to_int8_custom(text) AS IMPLICIT; postgres=> INSERT INTO test_cast VALUES ('123'::text); INSERT 0 1 postgres=> SELECT * FROM test_cast WHERE col='123'::text; col ----- 123 (1 row)

Con questa strategia, solo il cast int8 è implicito, quindi PostgreSQL può determinare in modo inequivocabile quale cast utilizzare.