

 Amazon Redshift non supporterà più la creazione di nuovi Python UDFs a partire dalla Patch 198. Python esistente UDFs continuerà a funzionare fino al 30 giugno 2026. Per ulteriori informazioni, consulta il [post del blog](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

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

# CREATE EXTERNAL FUNCTION
<a name="r_CREATE_EXTERNAL_FUNCTION"></a>

Crea una funzione scalare definita dall'utente (UDF) basata su Amazon AWS Lambda Redshift. Per ulteriori informazioni sulle funzioni Lambda definite dall'utente, consultare [Lambda scalare UDFs](udf-creating-a-lambda-sql-udf.md).

## Privilegi richiesti
<a name="r_CREATE_EXTERNAL_FUNCTION-privileges"></a>

Di seguito sono riportati i privilegi necessari per CREATE EXTERNAL FUNCTION:
+ Superuser
+ Utenti con il privilegio CREATE [ OR REPLACE ] EXTERNAL FUNCTION

## Sintassi
<a name="r_CREATE_EXTERNAL_FUNCTION-synopsis"></a>

```
CREATE [ OR REPLACE ] EXTERNAL FUNCTION external_fn_name ( [data_type] [, ...] )
RETURNS data_type
{ VOLATILE | STABLE }
LAMBDA 'lambda_fn_name'
IAM_ROLE { default | ‘arn:aws:iam::<Account AWS-id>:role/<role-name>’
RETRY_TIMEOUT milliseconds
MAX_BATCH_ROWS count
MAX_BATCH_SIZE size [ KB | MB ];
```

## Parameters
<a name="r_CREATE_EXTERNAL_FUNCTION-parameters"></a>

OR REPLACE  
Una clausola che specifica che se una funzione con stesso nome e tipi di dati degli argomenti di input o *firma* è già esistente, la funzione esistente viene sostituita. Puoi sostituire una funzione solo con una nuova funzione che definisce un set identico di tipi di dati. Devi essere un utente con privilegi avanzati per sostituire una funzione.  
Se definisci una funzione con lo stesso nome di una funzione esistente ma con una firma diversa, viene creata una nuova funzione. In altre parole, il nome della funzione è sottoposto a overload. Per ulteriori informazioni, consulta [Overload dei nomi delle funzioni](udf-naming-udfs.md#udf-naming-overloading-function-names).

*external\$1fn\$1name*  
Il nome della funzione esterna. Se si specifica un nome schema (come myschema.myfunction), la funzione viene creata utilizzando lo schema specificato. Altrimenti, la funzione viene creata nello schema corrente. Per ulteriori informazioni sui nomi validi, consultare [Nomi e identificatori](r_names.md).   
Consigliamo di assegnare un prefisso `f_` ai nomi di tutte le funzioni definite dall'utente. Amazon Redshift riserva il prefisso `f_` per i nomi delle funzioni definite dall'utente. Utilizzando il prefisso `f_`, è possibile assicurarsi che il nome della funzione non sia in conflitto con i nomi delle funzioni SQL predefinite di Amazon Redshift correnti e future. Per ulteriori informazioni, consulta [Prevenzione dei conflitti di denominazione delle funzioni definite dall'utente](udf-naming-udfs.md).

*data\$1type*  
Il tipo di dati per gli argomenti di input. Per ulteriori informazioni, consultare [Python scalare UDFs](udf-creating-a-scalar-udf.md) e [Lambda scalare UDFs](udf-creating-a-lambda-sql-udf.md).

RETURNS *data\$1type*  
Il tipo di dati del valore restituito dalla funzione. Il tipo di dati RETURNS può essere qualsiasi tipo di dati standard Amazon Redshift. Per ulteriori informazioni, consultare [Python scalare UDFs](udf-creating-a-scalar-udf.md) e [Lambda scalare UDFs](udf-creating-a-lambda-sql-udf.md).

VOLATILE \$1 STABILE  
Informa l'ottimizzatore di query circa la volatilità della funzione.   
Per ottenere la migliore ottimizzazione, etichettare la funzione con la categoria di volatilità più rigida valida. In ordine di rigidità, a partire dalla meno rigida, le categorie di volatilità sono le seguenti:  
+ VOLATILE
+ STABLE
VOLATILE  
Dati gli stessi argomenti, la funzione può restituire risultati diversi su chiamate successive, anche per le righe in una singola istruzione. L'ottimizzatore di query non può fare alcuna ipotesi sul comportamento di una funzione volatile. Una query che utilizza una funzione volatile deve rivalutare la funzione per ogni input.  
STABLE  
Dati gli stessi argomenti, la funzione è garantita per restituire gli stessi risultati nelle chiamate successive elaborate all'interno di una singola istruzione. La funzione può restituire risultati diversi se richiamati in istruzioni diverse. Questa categoria consente all'ottimizzatore di ridurre il numero di volte in cui la funzione viene chiamata all'interno di una singola istruzione.  
Nota che se la severità scelta non è valida per la funzione, c'è il rischio che l'ottimizzatore salti alcune chiamate in base a questa severità. Ciò può comportare un set di risultati errato.  
La clausola IMMUTABLE non è attualmente supportata per Lambda. UDFs

LAMBDA *'lambda\$1fn\$1name'*   
 Il nome della funzione richiamata da Amazon Redshift.  
Per i passaggi per creare una AWS Lambda funzione, consulta [Creare una funzione Lambda con la console nella Guida](https://docs.aws.amazon.com/lambda/latest/dg/getting-started-create-function.html) per gli *AWS Lambda sviluppatori*.  
Per informazioni sulle autorizzazioni richieste per la funzione Lambda, consultare [Autorizzazioni AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/lambda-permissions.html) nella *Guida per gli sviluppatori di AWS Lambda *.

IAM\$1ROLE \$1default \$1 'arn:aws:iam: :role/ '*<Account AWS-id>**<role-name>*   
Utilizzare la parola chiave predefinita per fare in modo che Amazon Redshift utilizzi il ruolo IAM impostato come predefinito e associato al cluster quando viene eseguito il comando CREATE EXTERNAL FUNCTION.  
L'Amazon Resource Name (ARN) per un ruolo IAM utilizzato dal cluster per l'autenticazione e l'autorizzazione. Il comando CREATE EXTERNAL FUNCTION è autorizzato per il richiamo delle funzioni Lambda tramite questo ruolo IAM. Se il cluster possiede un ruolo IAM esistente con autorizzazioni per richiamare funzioni Lambda collegate, è possibile sostituire l'ARN del ruolo. Per ulteriori informazioni, consulta [Configurazione del parametro di autorizzazione per Lambda UDFs](udf-creating-a-lambda-sql-udf.md#udf-lambda-authorization).  
Di seguito è mostrata la sintassi del parametro IAM\$1ROLE.  

```
IAM_ROLE 'arn:aws:iam::aws-account-id:role/role-name'
```

RETRY\$1TIMEOUT *millisecondi*   
La quantità di tempo totale, espressa in millisecondi, utilizzata da Amazon Redshift per i ritardi nei backoff dei tentativi.   
Invece di riprovare immediatamente per eventuali query non riuscite, Amazon Redshift esegue i backoff e attende un certo periodo di tempo tra i tentativi. Quindi Amazon Redshift riprova la richiesta di eseguire nuovamente la query non riuscita fino a quando la somma di tutti i ritardi è uguale o superiore al valore RETRY\$1TIMEOUT specificato. Il valore di default è 20.000 millisecondi.  
Quando viene richiamata una funzione Lambda, Amazon Redshift prova a eseguire nuovamente le query che ricevono errori come `TooManyRequestsException`, `EC2ThrottledException` e `ServiceException`.   
È possibile impostare il parametro RETRY\$1TIMEOUT su 0 millisecondi per evitare nuovi tentativi per una funzione Lambda definita dall'utente.

MAX\$1BATCH\$1ROWS *count*  
 Numero massimo di righe che Amazon Redshift invia in una singola richiesta batch per una singola chiamata lambda.   
 Il valore minimo per questo parametro è 1. Il valore massimo è INT\$1MAX o 2.147.483.647.   
 Questo parametro è facoltativo. Il valore predefinito è INT\$1MAX o 2.147.483.647. 

MAX\$1BATCH\$1SIZE *size* [ KB \$1 MB ]   
 La dimensione massima del payload di dati che Amazon Redshift invia in una singola richiesta batch per una singola chiamata lambda.   
 Il valore minimo per questo parametro è 1 KB. Il valore massimo è 5 MB.   
 Il valore predefinito di questo parametro è 5 MB.   
 KB e MB sono facoltativi. Se non si imposta l'unità di misura, Amazon Redshift utilizza per impostazione predefinita KB. 

## Note per l'utilizzo
<a name="r_CREATE_FUNCTION-usage-notes"></a>

Considera quanto segue quando crei UDFs Lambda: 
+ L'ordine delle chiamate alla funzione Lambda sugli argomenti di input non è fisso o garantito. Può variare tra le istanze di esecuzione delle query, a seconda della configurazione del cluster.
+ Non è garantito che le funzioni vengano applicate a ciascun argomento di input una sola volta. L'interazione tra Amazon Redshift e AWS Lambda potrebbe portare a chiamate ripetitive con gli stessi input.

## Esempi
<a name="r_CREATE_FUNCTION-examples"></a>

Di seguito sono riportati alcuni esempi di utilizzo delle funzioni scalari definite dall'utente Lambda (). UDFs

### Esempio di funzione Lambda definita dall'utente scalare che utilizza una funzione Lambda Node.js
<a name="r_CREATE_FUNCTION-lambda-example-node"></a>

L'esempio seguente crea una funzione esterna denominata `exfunc_sum` che utilizza due numeri interi come argomenti di input. Questa funzione restituisce la somma come output intero. Il nome della funzione Lambda da chiamare è `lambda_sum`. La lingua utilizzata per questa funzione Lambda è Node.js 12.x. Assicurarsi di specificare il ruolo IAM. L'esempio utilizza `'arn:aws:iam::123456789012:user/johndoe'` come ruolo IAM.

```
CREATE EXTERNAL FUNCTION exfunc_sum(INT,INT)
RETURNS INT
VOLATILE
LAMBDA 'lambda_sum'
IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test';
```

La funzione Lambda accetta il payload della richiesta ed esegue l'iterazione su ogni riga. Tutti i valori di una singola riga vengono aggiunti per calcolare la somma per quella riga, che viene salvata nell'array di risposte. Il numero di righe nell'array dei risultati è simile al numero di righe ricevute nel payload della richiesta. 

Perché sia riconosciuto dalla funzione esterna, il payload della risposta JSON deve avere i dati di risultato nel campo 'results'. Il campo argomenti nella richiesta inviata alla funzione Lambda contiene il payload dei dati. In caso di richiesta batch, è possibile avere più righe nel payload dei dati. La seguente funzione Lambda itera su tutte le righe nel payload dei dati della richiesta. Inoltre, itera individualmente su tutti i valori all'interno di una singola riga.

```
exports.handler = async (event) => {
    // The 'arguments' field in the request sent to the Lambda function contains the data payload.
    var t1 = event['arguments'];

    // 'len(t1)' represents the number of rows in the request payload.
    // The number of results in the response payload should be the same as the number of rows received.
    const resp = new Array(t1.length);

    // Iterating over all the rows in the request payload.
    for (const [i, x] of t1.entries())
    {
        var sum = 0;
        // Iterating over all the values in a single row.
        for (const y of x) {
            sum = sum + y;
        }
        resp[i] = sum;
    }
    // The 'results' field should contain the results of the lambda call.
    const response = {
        results: resp
    };
    return JSON.stringify(response);
};
```

Nell'esempio seguente viene chiamata la funzione esterna con valori letterali.

```
select exfunc_sum(1,2);
exfunc_sum
------------
 3
(1 row)
```

Nell'esempio seguente viene creata una tabella denominata t\$1sum con due colonne, c1 e c2, del tipo di dati intero e vengono inserite due righe di dati. Quindi la funzione esterna viene chiamata passando i nomi delle colonne di questa tabella. Le due righe della tabella vengono inviate in una richiesta batch nel payload della richiesta come un singolo richiamo Lambda.

```
CREATE TABLE t_sum(c1 int, c2 int);
INSERT INTO t_sum VALUES (4,5), (6,7);
SELECT exfunc_sum(c1,c2) FROM t_sum;
 exfunc_sum
---------------
 9
 13
(2 rows)
```

### Esempio di funzione Lambda definita dall'utente scalare che utilizza l'attributo RETRY\$1TIMEOUT
<a name="r_CREATE_FUNCTION-lambda-example-retry"></a>

Nella sezione seguente, puoi trovare un esempio di come utilizzare l'attributo RETRY\$1TIMEOUT in Lambda. UDFs 

AWS Lambda le funzioni hanno limiti di concorrenza che è possibile impostare per ciascuna funzione. Per ulteriori informazioni sui limiti di concorrenza, consulta [Gestire la concorrenza per una funzione Lambda](https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html) nella *Guida per gli AWS Lambda sviluppatori* e il post [Managing AWS Lambda Function Concurrency](https://aws.amazon.com/blogs/compute/managing-aws-lambda-function-concurrency) sul blog di Compute. AWS 

Quando il numero di richieste servite da una funzione Lambda definita dall'utente supera i limiti di simultaneità, le nuove richieste ricevono l'errore `TooManyRequestsException`. La funzione Lambda definita dall'utente riprova su questo errore fino a quando la somma di tutti i ritardi tra le richieste inviate alla funzione Lambda è uguale o superiore al valore RETRY\$1TIMEOUT impostato. Il valore di default di RETRY\$1TIMEOUT è 20.000 millisecondi.

L'esempio seguente crea una funzione Lambda denominata `exfunc_sleep_3`. Questa funzione prende in carico il payload della richiesta, itera su ogni riga e converte l'input in maiuscolo. Quindi si interrompe per 3 secondi e restituisce il risultato. Il linguaggio utilizzato per questa funzione Lambda è Python 3.8. 

Il numero di righe nell'array dei risultati è simile al numero di righe ricevute nel payload della richiesta. Perché sia riconosciuto dalla funzione esterna, il payload della risposta JSON deve avere i dati di risultato nel campo `results`. Il campo `arguments` nella richiesta inviata alla funzione Lambda contiene il payload dei dati. In caso di richiesta batch, è possibile avere più righe nel payload dei dati.

Il limite di simultaneità per questa funzione è impostato specificatamente su 1 nella simultaneità riservata per dimostrare l'utilizzo dell'attributo RETRY\$1TIMEOUT. Quando l'attributo è impostato su 1, la funzione Lambda può servire solo una richiesta alla volta.

```
import json
import time
def lambda_handler(event, context):
    t1 = event['arguments']
    # 'len(t1)' represents the number of rows in the request payload.
    # The number of results in the response payload should be the same as the number of rows received.
    resp = [None]*len(t1)

    # Iterating over all rows in the request payload.
    for i, x in enumerate(t1):
        # Iterating over all the values in a single row.
        for j, y in enumerate(x):
            resp[i] = y.upper()

    time.sleep(3)
    ret = dict()
    ret['results'] = resp
    ret_json = json.dumps(ret)
    return ret_json
```

Di seguito, due esempi aggiuntivi illustrano l'attributo RETRY\$1TIMEOUT. Ognuno di essi richiama una singola funzione Lambda definita dall'utente. Durante il richiamo della funzione Lambda, ogni esempio esegue la stessa query SQL per richiamare la funzione Lambda da due sessioni di database simultanee contemporaneamente. Quando la prima query che richiama la funzione Lambda definita dall'utente viene servita dalla funzione, la seconda query riceve l'errore `TooManyRequestsException`. Questo risultato si verifica perché si imposta in modo specifico la simultaneità riservata nella funzione definita dall'utente su 1. Per informazioni su come configurare la simultaneità riservata per le funzioni Lambda, consultare [Configurazione della simultaneità riservata](https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html#configuration-concurrency-reservedconfiguration-concurrency-reserved).

Nel primo esempio che segue, l'attributo RETRY\$1TIMEOUT per la funzione Lambda definita dall'utente viene impostato su 0 millisecondi. Se la richiesta Lambda riceve una qualsiasi eccezione dalla funzione Lambda, Amazon Redshift non esegue alcun nuovo tentativo. Questo risultato si verifica perché l'attributo RETRY\$1TIMEOUT è impostato su 0.

```
CREATE OR REPLACE EXTERNAL FUNCTION exfunc_upper(varchar)
RETURNS varchar
VOLATILE
LAMBDA 'exfunc_sleep_3'
IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test'
RETRY_TIMEOUT 0;
```

Con RETRY\$1TIMEOUT impostato su 0, è possibile eseguire le seguenti due query da sessioni di database separate e visualizzare risultati diversi.

La prima query SQL che utilizza la funzione Lambda definita dall'utente viene eseguita correttamente.

```
select exfunc_upper('Varchar');
 exfunc_upper
 --------------
 VARCHAR
(1 row)
```

La seconda query, eseguita contemporaneamente da una sessione di database separata, riceve l'errore `TooManyRequestsException`.

```
select exfunc_upper('Varchar');
ERROR:  Rate Exceeded.; Exception: TooManyRequestsException; ShouldRetry: 1
DETAIL:
-----------------------------------------------
error:  Rate Exceeded.; Exception: TooManyRequestsException; ShouldRetry: 1
code:      32103
context:query:     0
location:  exfunc_client.cpp:102
process:   padbmaster [pid=26384]
-----------------------------------------------
```

Nel primo esempio che segue, l'attributo RETRY\$1TIMEOUT per la funzione Lambda definita dall'utente viene impostato su 3.000 millisecondi. Anche se la seconda query viene eseguita contemporaneamente, la funzione Lambda definita dall'utente tenta di nuovo fino a quando il ritardo totale è di 3.000 millisecondi. Pertanto, entrambe le query vengono eseguite correttamente.

```
CREATE OR REPLACE EXTERNAL FUNCTION exfunc_upper(varchar)
RETURNS varchar
VOLATILE
LAMBDA 'exfunc_sleep_3'
IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test'
RETRY_TIMEOUT 3000;
```

Con RETRY\$1TIMEOUT impostato su 3.000 millisecondi, è possibile eseguire le seguenti due query da sessioni di database separate e visualizzare gli stessi risultati.

La prima query SQL che esegue la funzione Lambda definita dall'utente viene eseguita correttamente.

```
select exfunc_upper('Varchar');
 exfunc_upper
 --------------
 VARCHAR
(1 row)
```

La seconda query viene eseguita contemporaneamente e la funzione Lambda definita dall'utente prova di nuovo fino a quando il ritardo totale è di 3.000 millisecondi.

```
select exfunc_upper('Varchar');
 exfunc_upper
--------------
 VARCHAR
(1 row)
```

### Esempio di funzione Lambda definita dall'utente scalare che utilizza una funzione Lambda Python
<a name="r_CREATE_FUNCTION-lambda-example-python"></a>

L'esempio seguente crea una funzione esterna denominata `exfunc_multiplication` e che moltiplica i numeri e restituisce un numero intero. Questo esempio incorpora il successo e i campi `error_msg` nella risposta Lambda. Il campo di successo è impostato su false quando c'è un overflow di numeri interi nel risultato della moltiplicazione e il messaggio `error_msg` è impostato su `Integer multiplication overflow`. La funzione `exfunc_multiplication` accetta tre numeri interi come argomenti di input e restituisce la somma come output intero. 

Il nome della funzione Lambda richiamata è `lambda_multiplication`. Il linguaggio utilizzato per questa funzione Lambda è Python 3.8. Assicurarsi di specificare il ruolo IAM.

```
CREATE EXTERNAL FUNCTION exfunc_multiplication(int, int, int)
RETURNS INT
VOLATILE
LAMBDA 'lambda_multiplication'
IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test';
```

La funzione Lambda accetta il payload della richiesta ed esegue l'iterazione su ogni riga. Tutti i valori di una singola riga vengono moltiplicati per calcolare il risultato di tale riga, che viene salvato nell'elenco delle risposte. In questo esempio viene utilizzato un valore di successo booleano impostato su true per impostazione predefinita. Se il risultato della moltiplicazione per una riga ha un overflow intero, il valore di successo è impostato su false. Quindi il ciclo di iterazione si interrompe. 

Durante la creazione del payload di risposta, se il valore di successo è false, la seguente funzione Lambda aggiunge il campo `error_msg` nel payload. Imposta anche il messaggio di errore su `Integer multiplication overflow`. Se il valore di successo è true, i dati dei risultati vengono aggiunti nel campo dei risultati. Il numero di righe nell'array dei risultati, se presente, è simile al numero di righe ricevute nel payload della richiesta. 

Il campo argomenti nella richiesta inviata alla funzione Lambda contiene il payload dei dati. In caso di richiesta batch, è possibile avere più righe nel payload dei dati. La seguente funzione Lambda itera su tutte le righe nel payload dei dati richiesta e itera individualmente su tutti i valori all'interno di una singola riga. 

```
import json
def lambda_handler(event, context):
    t1 = event['arguments']
    # 'len(t1)' represents the number of rows in the request payload.
    # The number of results in the response payload should be the same as the number of rows received.
    resp = [None]*len(t1)

    # By default success is set to 'True'.
    success = True
    # Iterating over all rows in the request payload.
    for i, x in enumerate(t1):
        mul = 1
        # Iterating over all the values in a single row.
        for j, y in enumerate(x):
            mul = mul*y

        # Check integer overflow.
        if (mul >= 9223372036854775807 or mul <= -9223372036854775808):
            success = False
            break
        else:
            resp[i] = mul
    ret = dict()
    ret['success'] = success
    if not success:
        ret['error_msg'] = "Integer multiplication overflow"
    else:
        ret['results'] = resp
    ret_json = json.dumps(ret)

    return ret_json
```

Nell'esempio seguente viene chiamata la funzione esterna con valori letterali.

```
SELECT exfunc_multiplication(8, 9, 2);
  exfunc_multiplication
---------------------------
          144
(1 row)
```

Nell'esempio seguente viene creata una tabella denominata t\$1multi con tre colonne, c1, c2 e c3, del tipo di dati intero. La funzione esterna viene chiamata passando i nomi delle colonne di questa tabella. I dati vengono inseriti in modo tale da causare l'overflow di interi per mostrare come l'errore viene propagato.

```
CREATE TABLE t_multi (c1 int, c2 int, c3 int);
INSERT INTO t_multi VALUES (2147483647, 2147483647, 4);
SELECT exfunc_multiplication(c1, c2, c3) FROM t_multi;
DETAIL:
  -----------------------------------------------
  error:  Integer multiplication overflow
  code:      32004context:
  context:
  query:     38
  location:  exfunc_data.cpp:276
  process:   query2_16_38 [pid=30494]
  -----------------------------------------------
```