

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à.

# 
<a name="PostgreSQL.CustomCasts"></a>

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.](https://www.postgresql.org/docs/current/sql-createcast.html)

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

**Topics**
+ [Installazione e utilizzo dell'estensione rds\$1casts](#PostgreSQL.CustomCasts.Installing)
+ [Cast supportati](#PostgreSQL.CustomCasts.Supported)
+ [Creare o eliminare cast](#PostgreSQL.CustomCasts.Creating)
+ [Creazione di cast personalizzati con una strategia contestuale adeguata](#PostgreSQL.CustomCasts.BestPractices)

## Installazione e utilizzo dell'estensione rds\$1casts
<a name="PostgreSQL.CustomCasts.Installing"></a>

Per creare l'`rds_casts`estensione, connettiti all' ed esegui il comando seguente: `rds_superuser`

```
CREATE EXTENSION IF NOT EXISTS rds_casts;
```

## Cast supportati
<a name="PostgreSQL.CustomCasts.Supported"></a>

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\$1casts fornisce due tipi di funzioni di conversione per ogni cast:
+ *funzioni \$1inout*: utilizzano il meccanismo di I/O conversione standard di PostgreSQL, che si comporta in modo identico ai cast creati con il metodo INOUT
+ *\$1custom 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
<a name="PostgreSQL.CustomCasts.Creating"></a>

Puoi creare e eliminare i cast supportati utilizzando due metodi:

### Creazione di cast
<a name="PostgreSQL.CustomCasts.Creating.Methods"></a>

**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\$1casts.create\$1cast**

```
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\$1cast:

```
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
<a name="PostgreSQL.CustomCasts.Dropping"></a>

**Metodo 1: utilizzo del comando DROP CAST**

```
DROP CAST IF EXISTS (text AS numeric);
```

**Metodo 2: utilizzo della funzione rds\$1casts.drop\$1cast**

```
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
<a name="PostgreSQL.CustomCasts.BestPractices"></a>

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.