

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

# Utilizzo di elementi e attributi in DynamoDB
<a name="WorkingWithItems"></a>

In Amazon DynamoDB, un *elemento* è una raccolta di attributi. Ogni attributo ha un nome e un valore. Il valore di un attributo può essere un tipo scalare, un set o un tipo di documento. Per ulteriori informazioni, consulta [Amazon DynamoDB: come funziona](HowItWorks.md).

DynamoDB fornisce quattro operazioni per le funzionalità di creazione, lettura, aggiornamento ed eliminazione CRUD (create/read/update/delete) di base. Tutte queste operazioni sono atomiche.
+ `PutItem`: crea un elemento.
+ `GetItem`: legge un elemento.
+ `UpdateItem`: aggiorna un elemento.
+ `DeleteItem`: elimina un elemento.

Ognuna di queste operazioni richiede di specificare la chiave primaria dell'elemento da usare. Per leggere, ad esempio, un elemento con `GetItem`, devi specificare la chiave di partizione e la chiave di ordinamento (se applicabile) per l'elemento.

Oltre alle quattro operazioni CRUD di base, DynamoDB fornisce anche le seguenti funzionalità:
+ `BatchGetItem`: legge fino a 100 elementi da una o più tabelle.
+ `BatchWriteItem`: crea o elimina fino a 25 elementi in una o più tabelle.

Queste operazioni batch combinano diverse operazioni CRUD in una singola richiesta. Le operazioni batch, inoltre, leggono e scrivono gli elementi in parallelo, per ridurre al minimo la latenza delle risposte.

In questa sezione viene descritto come usare queste operazioni e sono inclusi argomenti correlati, come gli aggiornamenti condizionali e i contatori atomici. Questa sezione include anche un codice di esempio che utilizza il AWS SDKs. 

**Topics**
+ [

# Dimensioni e formati degli elementi di DynamoDB
](CapacityUnitCalculations.md)
+ [

## Lettura di un elemento
](#WorkingWithItems.ReadingData)
+ [

## Scrittura di un elemento
](#WorkingWithItems.WritingData)
+ [

## Valori restituiti
](#WorkingWithItems.ReturnValues)
+ [

## Operazioni batch
](#WorkingWithItems.BatchOperations)
+ [

## Contatori atomici
](#WorkingWithItems.AtomicCounters)
+ [

## Scritture condizionali
](#WorkingWithItems.ConditionalUpdate)
+ [

# Utilizzo di espressioni in DynamoDB
](Expressions.md)
+ [

# Utilizzo del Time to Live in DynamoDB
](TTL.md)
+ [

# Esecuzione di query in DynamoDB
](Query.md)
+ [

# Scansione di tabelle in DynamoDB
](Scan.md)
+ [

# PartiQL: un linguaggio di query compatibile con SQL per Amazon DynamoDB
](ql-reference.md)
+ [

# Utilizzo degli elementi: Java
](JavaDocumentAPIItemCRUD.md)
+ [

# Uso di elementi: .NET
](LowLevelDotNetItemCRUD.md)

# Dimensioni e formati degli elementi di DynamoDB
<a name="CapacityUnitCalculations"></a>

Le tabelle DynamoDB non hanno uno schema, tranne per la chiave primaria, pertanto gli elementi in una tabella possono avere attributi, dimensioni e tipi di dati diversi.

La dimensione totale di un elemento è data dalla somma delle lunghezze dei nomi e dei valori dei relativi attributi, più eventuali overhead applicabili come descritto di seguito. Per stimare le dimensioni degli attributi, puoi utilizzare le linee guida seguenti:
+ Le stringhe sono Unicode con codifica binaria UTF-8. La dimensione di una stringa è *(numero di byte con codifica UTF-8 del nome dell’attributo) \$1 (numero di byte con codifica UTF-8)*.
+ I numeri hanno lunghezza variabile, con un massimo di 38 cifre significative. Gli zero iniziali e finali vengono tagliati. La dimensione di un numero è circa *(numero di byte con codifica UTF-8 del nome dell’attributo) \$1 (1 byte ogni due cifre significative) \$1 (1 byte)*.
+ Un valore binario deve essere codificato in formato base64 per essere inviato a DynamoDB, ma per il calcolo della dimensione viene utilizzata la lunghezza dei byte in formato RAW del valore. La dimensione di un attributo di tipo binario è *(numero di byte con codifica UTF-8 del nome dell’attributo) \$1 (numero di byte in formato RAW).*
+ La dimensione di un attributo null o booleano è *(numero di byte con codifica UTF-8 del nome dell’attributo) \$1 (1 byte)*.
+ Un attributo di tipo `List` o `Map` richiede 3 byte di overhead, indipendentemente dal contenuto. La dimensione di un `List` o di una `Map` è *(numero di byte con codifica UTF-8 del nome dell’attributo) \$1 somma (dimensione degli elementi annidati) \$1 (3 byte)*. La dimensione di un `List` o di una `Map` vuoti è *(numero di byte con codifica UTF-8 del nome dell’attributo) \$1 (3 byte)*.
+ Ogni elemento `List` o `Map` richiede anche un byte di sovraccarico.

**Nota**  
È consigliabile preferire nomi di attributo brevi piuttosto che lunghi. Ciò consente di ridurre la quantità di spazio di archiviazione richiesta, ma può anche ridurre la quantità RCU/WCUs di spazio utilizzato.

Ai fini della fatturazione dell'archiviazione, ogni elemento include un overhead di archiviazione per elemento che dipende dalle funzionalità abilitate.
+ Tutti gli elementi in DynamoDB richiedono 100 byte di overhead di archiviazione per l'indicizzazione.
+ Alcune funzionalità DynamoDB (tabelle globali, transazioni, acquisizione dei dati di modifica per Kinesis Data Streams con DynamoDB) richiedono un overhead di archiviazione aggiuntivo per tenere conto degli attributi creati dal sistema derivanti dall'abilitazione di tali funzionalità. Ad esempio, le tabelle globali richiedono un overhead aggiuntivo di 48 byte di archiviazione.

## Lettura di un elemento
<a name="WorkingWithItems.ReadingData"></a>

Per leggere un elemento da una tabella DynamoDB, utilizza l'operazione `GetItem`. Devi fornire il nome della tabella e la chiave primaria dell'elemento desiderato.

**Example**  
L' AWS CLI esempio seguente mostra come leggere un elemento dalla `ProductCatalog` tabella.  

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}'
```

**Nota**  
Con `GetItem`, devi specificare l'*intera* chiave primaria, non una parte di essa. Se, ad esempio, una tabella ha una chiave primaria composita (chiave di partizione e chiave di ordinamento), devi fornire un valore per la chiave di partizione e uno per la chiave di ordinamento.

Una richiesta `GetItem` esegue una lettura consistente finale per impostazione predefinita. Puoi usare il parametro `ConsistentRead` per richiedere invece una lettura consistente assoluta. (Ciò consuma unità di capacità di lettura aggiuntive, ma restituisce la maggior parte delle up-to-date versioni dell'articolo.)

`GetItem` restituisce tutti gli attributi dell'elemento. Puoi usare un'*espressione di proiezione* per restituire solo alcuni degli attributi. Per ulteriori informazioni, consulta [Utilizzo di espressioni di proiezione in DynamoDB](Expressions.ProjectionExpressions.md).

Per restituire il numero di unità di capacità di lettura utilizzate da `GetItem`, imposta il parametro `ReturnConsumedCapacity` su `TOTAL`.

**Example**  
L'esempio seguente AWS Command Line Interface (AWS CLI) mostra alcuni `GetItem` parametri opzionali.  

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --consistent-read \
    --projection-expression "Description, Price, RelatedItems" \
    --return-consumed-capacity TOTAL
```

## Scrittura di un elemento
<a name="WorkingWithItems.WritingData"></a>

Per creare, aggiornare o eliminare un elemento in una tabella DynamoDB, utilizza una delle operazioni seguenti:
+ `PutItem`
+ `UpdateItem`
+ `DeleteItem`

Per ognuna di queste operazioni, devi specificare l'intera chiave primaria e non solo una parte di essa. Se, ad esempio, una tabella ha una chiave primaria composita (chiave di partizione e chiave di ordinamento), devi fornire un valore per la chiave di partizione e uno per la chiave di ordinamento.

Per restituire il numero di unità di capacità di scrittura utilizzate da queste operazioni, imposta il parametro `ReturnConsumedCapacity` su uno dei valori seguenti: 
+ `TOTAL`: restituisce il numero totale di unità di capacità di scrittura totali consumate.
+ `INDEXES`: restituisce il numero totale di unità di capacità di scrittura consumate, con i subtotali per la tabella e gli eventuali indici secondari interessati dall'operazione.
+ `NONE`: non vengono restituiti dettagli sulla capacità di scrittura. Questa è l'impostazione predefinita.

### PutItem
<a name="WorkingWithItems.WritingData.PutItem"></a>

`PutItem` crea un nuovo elemento. Se nella tabella esiste già un elemento con la stessa chiave, il nuovo elemento sostituisce quello esistente.

**Example**  
Scrivi un nuovo elemento nella tabella `Thread`. La chiave primaria per `Thread` è costituita da `ForumName` (chiave di partizione) e `Subject` (chiave di ordinamento).  

```
aws dynamodb put-item \
    --table-name Thread \
    --item file://item.json
```
Gli argomenti per `--item` sono memorizzati nel file `item.json`:  

```
{
    "ForumName": {"S": "Amazon DynamoDB"},
    "Subject": {"S": "New discussion thread"},
    "Message": {"S": "First post in this thread"},
    "LastPostedBy": {"S": "fred@example.com"},
    "LastPostDateTime": {"S": "201603190422"}
}
```

### UpdateItem
<a name="WorkingWithItems.WritingData.UpdateItem"></a>

Se non esiste un elemento con la chiave specificata, `UpdateItem` crea un nuovo elemento. In caso contrario, modifica gli attributi di un elemento esistente.

Puoi usare un'*espressione di aggiornamento* per specificare gli attributi che desideri modificare e i loro nuovi valori. Per ulteriori informazioni, consulta [Utilizzo di espressioni di aggiornamento in DynamoDB](Expressions.UpdateExpressions.md). 

Nell'espressione di aggiornamento usi i valori degli attributi di espressione come segnaposto per i valori effettivi. Per ulteriori informazioni, consulta [Utilizzo dei valori degli attributi di espressione in DynamoDB](Expressions.ExpressionAttributeValues.md).

**Example**  
Modifica i diversi attributi nell'elemento `Thread`. Il parametro `ReturnValues` facoltativo mostra l'elemento dopo l'aggiornamento. Per ulteriori informazioni, consulta [Valori restituiti](#WorkingWithItems.ReturnValues).  

```
aws dynamodb update-item \
    --table-name Thread \
    --key file://key.json \
    --update-expression "SET Answered = :zero, Replies = :zero, LastPostedBy = :lastpostedby" \
    --expression-attribute-values file://expression-attribute-values.json \
    --return-values ALL_NEW
```

Gli argomenti per `--key` sono memorizzati nel file `key.json`:

```
{
    "ForumName": {"S": "Amazon DynamoDB"},
    "Subject": {"S": "New discussion thread"}
}
```

Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `expression-attribute-values.json`:

```
{
    ":zero": {"N":"0"},
    ":lastpostedby": {"S":"barney@example.com"}
}
```

### DeleteItem
<a name="WorkingWithItems.WritingData.DeleteItem"></a>

`DeleteItem` elimina l'elemento con la chiave specificata.

**Example**  
L' AWS CLI esempio seguente mostra come eliminare l'`Thread`elemento.  

```
aws dynamodb delete-item \
    --table-name Thread \
    --key file://key.json
```

## Valori restituiti
<a name="WorkingWithItems.ReturnValues"></a>

In alcuni casi potrebbe essere necessario che DynamoDB restituisca determinati valori degli attributi nello stato in cui si trovano prima o dopo la modifica. Le operazioni `PutItem`, `UpdateItem` e `DeleteItem` hanno un parametro `ReturnValues` che è possibile usare per restituire i valori degli attributi prima o dopo la modifica.

Il valore predefinito per `ReturnValues` è `NONE`, il che significa che DynamoDB non restituisce informazioni sugli attributi che sono stati modificati. 

Di seguito sono illustrate le altre impostazioni valide per `ReturnValues`, organizzate in base all'operazione API di DynamoDB.

### PutItem
<a name="WorkingWithItems.ReturnValues.PutItem"></a>
+ `ReturnValues`: `ALL_OLD`
  + Se sovrascrivi un elemento esistente, `ALL_OLD` restituisce l'intero elemento precedente alla sovrascrittura.
  + Se scrivi un elemento che non esiste, `ALL_OLD` non ha alcun effetto.

### UpdateItem
<a name="WorkingWithItems.ReturnValues.UpdateItem"></a>

L'uso più comune di `UpdateItem` è quello di aggiornare un elemento esistente. `UpdateItem` esegue tuttavia un'operazione *upsert*, ovvero crea automaticamente l'elemento, se non esiste già.
+ `ReturnValues`: `ALL_OLD`
  + Se aggiorni un elemento esistente, `ALL_OLD` restituisce l'intero elemento precedente all'aggiornamento.
  + Se aggiorni un item che non esiste (upsert), `ALL_OLD` non ha alcun effetto.
+ `ReturnValues`: `ALL_NEW`
  + Se aggiorni un elemento esistente, `ALL_NEW` restituisce l'intero elemento successivo all'aggiornamento.
  + Se aggiorni un elemento che non esiste (upsert), `ALL_NEW` restituisce l'intero elemento.
+ `ReturnValues`: `UPDATED_OLD`
  + Se aggiorni un elemento esistente, `UPDATED_OLD` restituisce solo gli attributi aggiornati, nello stato precedente all'aggiornamento.
  + Se aggiorni un item che non esiste (upsert), `UPDATED_OLD` non ha alcun effetto.
+ `ReturnValues`: `UPDATED_NEW`
  + Se aggiorni un elemento esistente, `UPDATED_NEW` restituisce solo gli attributi interessati, nello stato successivo all'aggiornamento.
  + Se aggiorni un elemento che non esiste (upsert), `UPDATED_NEW` restituisce solo gli attributi aggiornati, nello stato successivo all'aggiornamento.

### DeleteItem
<a name="WorkingWithItems.ReturnValues.DeleteItem"></a>
+ `ReturnValues`: `ALL_OLD`
  + Se elimini un elemento esistente, `ALL_OLD` restituisce l'intero elemento precedente all'eliminazione.
  + Se elimini un elemento che non esiste, `ALL_OLD` non restituisce alcun dato.

## Operazioni batch
<a name="WorkingWithItems.BatchOperations"></a>

Per le applicazioni che devono leggere o scrivere più elementi, DynamoDB fornisce le operazioni `BatchGetItem` e `BatchWriteItem`. L'uso di queste operazioni permette di ridurre il numero di viaggi di andata e ritorno di rete dall'applicazione a DynamoDB. Inoltre, DynamoDB esegue le singole operazioni di lettura o scrittura in parallelo. Le applicazioni possono ottenere un vantaggio da questo parallelismo, senza dover gestire la concorrenza o il threading.

Le operazioni batch sono essenzialmente una combinazione di più richieste di lettura o di scrittura. Se, ad esempio, una richiesta `BatchGetItem` contiene cinque elementi, DynamoDB esegue cinque operazioni `GetItem` per conto tuo. Analogamente, se una richiesta `BatchWriteItem` contiene due richieste put e quattro richieste delete, DynamoDB esegue due richieste `PutItem` e quattro richieste `DeleteItem`.

In generale, un'operazione batch non ha esito negativo a meno che *tutte* le richieste nel batch non abbiano esito negativo. Supponi, ad esempio, di eseguire un'operazione `BatchGetItem`, ma una delle singole richieste `GetItem` nel batch ha esito negativo. In questo caso, `BatchGetItem` restituisce le chiavi e i dati della richiesta `GetItem` che ha avuto esito negativo. Le altre richieste `GetItem` nel batch non sono interessate.

### BatchGetItem
<a name="WorkingWithItems.BatchOperations.BatchGetItem"></a>

Una singola operazione `BatchGetItem` può contenere fino a 100 singole richieste `GetItem` e può recuperare fino a 16 MB di dati. Un'operazione `BatchGetItem` può inoltre recuperare elementi da più tabelle.

**Example**  
Recupera due elementi dalla tabella `Thread` usando un'espressione di proiezione per restituire solo alcuni degli attributi.  

```
aws dynamodb batch-get-item \
    --request-items file://request-items.json
```
Gli argomenti per `--request-items` sono memorizzati nel file `request-items.json`:  

```
{
    "Thread": {
        "Keys": [
            {
                "ForumName":{"S": "Amazon DynamoDB"},
                "Subject":{"S": "DynamoDB Thread 1"}
            },
            {
                "ForumName":{"S": "Amazon S3"},
                "Subject":{"S": "S3 Thread 1"}
            }
        ],
        "ProjectionExpression":"ForumName, Subject, LastPostedDateTime, Replies"
    }
}
```

### BatchWriteItem
<a name="WorkingWithItems.BatchOperations.BatchWriteItem"></a>

L'operazione `BatchWriteItem` può contenere fino a 25 singole richieste `PutItem` e `DeleteItem` e può scrivere fino a 16 MB di dati. La dimensione massima di un singolo elemento è 400 KB. Un'operazione `BatchWriteItem` può inoltre inserire o eliminare elementi in più tabelle. 

**Nota**  
`BatchWriteItem` non supporta le richieste `UpdateItem`.

**Example**  
Scrivi due elementi nella tabella `ProductCatalog`.  

```
aws dynamodb batch-write-item \
    --request-items file://request-items.json
```
Gli argomenti per `--request-items` sono memorizzati nel file `request-items.json`:  

```
{
    "ProductCatalog": [
        {
            "PutRequest": {
                "Item": {
                    "Id": { "N": "601" },
                    "Description": { "S": "Snowboard" },
                    "QuantityOnHand": { "N": "5" },
                    "Price": { "N": "100" }
                }
            }
        },
        {
            "PutRequest": {
                "Item": {
                    "Id": { "N": "602" },
                    "Description": { "S": "Snow shovel" }
                }
            }
        }
    ]
}
```

## Contatori atomici
<a name="WorkingWithItems.AtomicCounters"></a>

È possibile utilizzare l'operazione `UpdateItem` per implementare un *contatore atomico*: un attributo numerico che viene incrementato, incondizionatamente, senza interferire con altre richieste di scrittura. Tutte le richieste di scrittura vengono applicate in base all'ordine di ricezione. Con un contatore atomico, gli aggiornamenti non sono idempotenti. In altre parole, il valore numerico aumenta o diminuisce a ogni chiamata di `UpdateItem`. Se il valore di incremento utilizzato per aggiornare il contatore atomico è positivo, può causare un conteggio in eccesso. Se il valore dell'incremento è negativo, può causare un conteggio in difetto.

Puoi usare un contatore atomico per tenere traccia del numero di visitatori di un sito Web. In questo caso, l'applicazione incrementa un valore numerico, indipendentemente dal valore corrente. Se un'operazione `UpdateItem` non va a buon fine, l'applicazione può semplicemente provare a ripetere l'operazione. Ciò rischierebbe di aggiornare il contatore due volte, anche se probabilmente un lieve discostamento in eccesso o in difetto nel numero di visitatori del sito Web può essere tollerato.

Un contatore atomico non è appropriato quando un conteggio maggiore o minore di quello effettivo non può essere tollerato (ad esempio, in un'applicazione bancaria). In questo caso, è preferibile usare un aggiornamento condizionale al posto di un contatore atomico.

Per ulteriori informazioni, consulta [Incremento e decremento di attributi numerici](Expressions.UpdateExpressions.md#Expressions.UpdateExpressions.SET.IncrementAndDecrement).

**Example**  
L' AWS CLI esempio seguente incrementa il valore `Price` di un prodotto di 5. In questo esempio, l’elemento esisteva già prima dell’aggiornamento del contatore. Poiché `UpdateItem` non è idempotente, il valore di `Price` aumenta ogni volta che si esegue il codice.   

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id": { "N": "601" }}' \
    --update-expression "SET Price = Price + :incr" \
    --expression-attribute-values '{":incr":{"N":"5"}}' \
    --return-values UPDATED_NEW
```

## Scritture condizionali
<a name="WorkingWithItems.ConditionalUpdate"></a>

Per impostazione predefinita, le operazioni di scrittura di DynamoDB `PutItem` (`DeleteItem`,) *sono* incondizionate: ogni operazione sovrascrive un elemento esistente con la chiave primaria specificata.

Facoltativamente, per queste operazioni DynamoDB supporta le scritture condizionali. Una scrittura condizionale ha esito positivo solo se gli attributi dell'elemento soddisfano una o più condizioni. In caso contrario, restituisce un errore.

Le scritture condizionali controllano le condizioni rispetto alla versione aggiornata più recente dell’elemento. Se l’elemento non esisteva in precedenza o se l’ultima operazione completata su quell’elemento è stata un’eliminazione, la scrittura condizionale non troverà alcun elemento precedente.

 Le operazioni di scrittura condizionali sono utili in molte situazioni. Potrebbe ad esempio essere necessario fare in modo che un'operazione `PutItem` abbia esito positivo solo se non è già presente un elemento con la stessa chiave primaria. In alternativa, si potrebbe impedire a un'operazione `UpdateItem` di modificare un elemento se uno o più dei relativi attributi ha un determinato valore.

Le scritture condizionali sono utili nei casi in cui più utenti tentano di modificare lo stesso elemento. Si consideri il diagramma seguente, in cui due utenti (Alice e Bob) stanno lavorando con lo stesso elemento in una tabella DynamoDB.

![\[Gli utenti Alice e Bob tentano di modificare un elemento con Id 1, dimostrando la necessità di scritture condizionali.\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/images/update-no-condition.png)


Supponiamo che Alice utilizzi l'attributo to per aggiornare l' AWS CLI attributo a 8. `Price`

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --update-expression "SET Price = :newval" \
    --expression-attribute-values file://expression-attribute-values.json
```

Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `expression-attribute-values.json`:

```
{
    ":newval":{"N":"8"}
}
```

Supponi ora che Bob esegua una richiesta `UpdateItem` simile in un secondo momento, modificando però il valore di `Price` in 12. Per Bob, l'aspetto del parametro `--expression-attribute-values` è simile al seguente.

```
{
    ":newval":{"N":"12"}
}
```

La richiesta di Bob ha esito positivo, ma l'aggiornamento precedente di Alice viene perso.

Per richiedere un'operazione `PutItem`, `DeleteItem` o `UpdateItem` condizionale, specifichi un'espressione di condizione. Un'*espressione condizionale* è una stringa contenente nomi di attributi, operatori condizionali e funzioni predefinite. L'intera espressione deve essere vera. In caso contrario, l'operazione non va a buon fine.

Considera ora il diagramma seguente, che mostra in che modo le scritture condizionali impedirebbero la sovrascrittura dell'aggiornamento di Alice.

![\[Scrittura condizionale che impedisce all’aggiornamento dell’utente Bob di sovrascrivere le modifiche dell’utente Alice allo stesso elemento.\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/images/update-yes-condition.png)


Alice prova innanzitutto ad aggiornare il valore di `Price` a 8, ma solo se il valore di `Price` corrente è 10.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --update-expression "SET Price = :newval" \
    --condition-expression "Price = :currval" \
    --expression-attribute-values file://expression-attribute-values.json
```

Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `expression-attribute-values.json`:

```
{
    ":newval":{"N":"8"},
    ":currval":{"N":"10"}
}
```

L'aggiornamento di Alice riesce perché la condizione è vera.

Bob cerca quindi di aggiornare il valore di `Price` a 12, ma solo se il valore di `Price` corrente è 10. Per Bob, l'aspetto del parametro `--expression-attribute-values` è simile al seguente.

```
{
    ":newval":{"N":"12"},
    ":currval":{"N":"10"}
}
```

Poiché in precedenza Alice ha modificato il valore di `Price` in 8, l'espressione condizionale è falsa e l'aggiornamento di Bob non riesce.

Per ulteriori informazioni, consulta [Esempio di CLI di espressione condizionale in DynamoDB](Expressions.ConditionExpressions.md).

### Idempotenza delle scritture condizionali
<a name="WorkingWithItems.ConditionalWrites.Idempotence"></a>

Le scritture condizionali possono essere *idempotenti* se la verifica condizionale è sullo stesso attributo in fase di aggiornamento. Ciò significa che DynamoDB esegue una certa richiesta di scrittura solo se determinati valori degli attributi nell'elemento corrispondono a quanto previsto al momento della richiesta. 

Supponi, ad esempio, di eseguire una richiesta `UpdateItem` per aumentare il valore di `Price` per un elemento di 3, ma solo se il valore di `Price` corrente è 20. Dopo che hai inviato la richiesta, ma prima di ricevere i risultati, si verifica un errore di rete e non sai se la richiesta ha avuto esito positivo. Poiché la scrittura condizionale è idempotente, è possibile eseguire di nuovo la stessa richiesta `UpdateItem` e DynamoDB aggiornerà l'elemento solo se il valore di `Price` corrente è 20.

### Unità di capacità utilizzate dalle scritture condizionali
<a name="WorkingWithItems.ConditionalWrites.ReturnConsumedCapacity"></a>

Se `ConditionExpression` restituisce false durante una scrittura condizionale, DynamoDB utilizza comunque la capacità di scrittura della tabella. La quantità consumata dipende dalla dimensione dell'elemento esistente (o almeno 1). Ad esempio, se un elemento esistente è di 300 KB e il nuovo elemento che si sta cercando di creare o aggiornare è 310 KB, le unità di capacità di scrittura consumate saranno 300 se la condizione restituisce un errore o 310 se la condizione riesce. Se si tratta di un elemento nuovo (non un elemento esistente), le unità di capacità di scrittura consumate saranno 1 se la condizione restituisce un errore e 310 se la condizione riesce.

**Nota**  
Le operazioni di scrittura utilizzano solo unità di capacità in *scrittura*. Non utilizzano mai unità di capacità in *lettura*.

Una scrittura condizionale non riuscita restituisce `ConditionalCheckFailedException`. In questo caso, non vengono inviate informazioni nella risposta sulla capacità di scrittura utilizzata.

Per restituire il numero di unità di capacità di scrittura utilizzate durante una scrittura condizionale, usa il parametro `ReturnConsumedCapacity`:
+ `TOTAL`: restituisce il numero totale di unità di capacità di scrittura totali consumate.
+ `INDEXES`: restituisce il numero totale di unità di capacità di scrittura consumate, con i subtotali per la tabella e gli eventuali indici secondari interessati dall'operazione.
+ `NONE`: non vengono restituiti dettagli sulla capacità di scrittura. Questa è l'impostazione predefinita.

  

**Nota**  
A differenza di un indice secondario globale, un indice secondario locale condivide la capacità di throughput assegnata con la relativa tabella. L'attività di lettura e scrittura su un indice secondario locale utilizza la capacità di throughput assegnata della tabella.

# Utilizzo di espressioni in DynamoDB
<a name="Expressions"></a>

In Amazon DynamoDB è possibile *utilizzare* le espressioni per specificare quali attributi leggere da un elemento, per scrivere dati quando viene soddisfatta una condizione, per specificare come aggiornare un elemento, per definire query e filtrare i risultati di una query.

Questa tabella descrive la grammatica delle espressioni di base e i tipi di espressioni disponibili.


| Tipo di espressione | Description | 
| --- | --- | 
| Espressioni di proiezione | Un'espressione di proiezione identifica gli attributi che si desidera recuperare da un elemento quando si utilizzano operazioni come Query o GetItem Scan. | 
| Espressione condizionale | Un'espressione di condizione determina quali elementi devono essere modificati quando si utilizzano le operazioni PutItem UpdateItem, e. DeleteItem  | 
| Espressione di aggiornamento | Un'espressione di aggiornamento specifica come UpdateItem verranno modificati gli attributi di un elemento, ad esempio l'impostazione di un valore scalare o la rimozione di elementi da un elenco o da una mappa. | 
| Espressione di condizione della chiave | Un’espressione di condizione della chiave determina gli elementi che una query leggerà da una tabella o da un indice. | 
| Espressione filtro | Un’espressione di filtro determina quali elementi all’interno dei risultati di Query devono essere restituiti. Tutti gli altri risultati vengono scartati. | 

Per ulteriori informazioni sulla sintassi delle espressioni e informazioni più dettagliate su ciascun tipo di espressione, consulta le sezioni riportate di seguito.

**Topics**
+ [

# Riferimento agli attributi degli elementi quando si utilizzano le espressioni in DynamoDB
](Expressions.Attributes.md)
+ [

# Nomi di attributi di espressione (alias) in DynamoDB
](Expressions.ExpressionAttributeNames.md)
+ [

# Utilizzo dei valori degli attributi di espressione in DynamoDB
](Expressions.ExpressionAttributeValues.md)
+ [

# Utilizzo di espressioni di proiezione in DynamoDB
](Expressions.ProjectionExpressions.md)
+ [

# Utilizzo di espressioni di aggiornamento in DynamoDB
](Expressions.UpdateExpressions.md)
+ [

# Espressioni, operatori e funzioni di condizione e di filtro in DynamoDB
](Expressions.OperatorsAndFunctions.md)
+ [

# Esempio di CLI di espressione condizionale in DynamoDB
](Expressions.ConditionExpressions.md)

**Nota**  
Per la compatibilità con le versioni precedenti, DynamoDB supporta anche parametri condizionali che non usano espressioni. Per ulteriori informazioni, consulta [Parametri condizionali legacy di DynamoDB](LegacyConditionalParameters.md).  
Le nuove applicazioni dovrebbero utilizzare le espressioni al posto dei parametri legacy.

# Riferimento agli attributi degli elementi quando si utilizzano le espressioni in DynamoDB
<a name="Expressions.Attributes"></a>

In questa sezione viene descritto come fare riferimento agli attributi degli elementi in una espressione in Amazon DynamoDB. Puoi utilizzare qualsiasi attributo, anche se è nidificato all'interno di più elenchi e mappe.

**Topics**
+ [

## Attributi di primo livello
](#Expressions.Attributes.TopLevelAttributes)
+ [

## Attributi nidificati
](#Expressions.Attributes.NestedAttributes)
+ [

## Percorsi dei documenti
](#Expressions.Attributes.NestedElements.DocumentPathExamples)

**Un articolo di esempio: ProductCatalog**  
Gli esempi presenti in questa pagina utilizzano il seguente elemento di esempio presente nella tabella `ProductCatalog`. (Questa tabella è descritta in [Tabelle e dati di esempio da utilizzare in DynamoDB](AppendixSampleTables.md)).

```
{
    "Id": 123,
    "Title": "Bicycle 123",
    "Description": "123 description",
    "BicycleType": "Hybrid",
    "Brand": "Brand-Company C",
    "Price": 500,
    "Color": ["Red", "Black"],
    "ProductCategory": "Bicycle",
    "InStock": true,
    "QuantityOnHand": null,
    "RelatedItems": [
        341,
        472,
        649
    ],
    "Pictures": {
        "FrontView": "http://example.com/products/123_front.jpg",
        "RearView": "http://example.com/products/123_rear.jpg",
        "SideView": "http://example.com/products/123_left_side.jpg"
    },
    "ProductReviews": {
	    "FiveStar": [
	    		"Excellent! Can't recommend it highly enough! Buy it!",
	    		"Do yourself a favor and buy this."
	    ],
	    "OneStar": [
	    		"Terrible product! Do not buy this."
	    ]
    },
    "Comment": "This product sells out quickly during the summer",
    "Safety.Warning": "Always wear a helmet"
 }
```

Tenere presente quanto segue:
+ il valore della chiave di partizione (`Id`) è `123`. Non vi è chiave di ordinamento;
+ la maggior parte degli attributi dispone di tipi di dati scalari, come `String`, `Number`, `Boolean` e `Null`;
+ un attributo (`Color`) è di tipo `String Set`;
+ i seguenti attributi sono tipi di dati dei documenti:
  + elenco di `RelatedItems`. Ogni elemento è un `Id` per un prodotto correlato;
  + una mappa di `Pictures`. Ogni elemento rappresenta una breve descrizione di un'immagine insieme all'URL del file dell'immagine corrispondente;
  + una mappa di `ProductReviews`. Ogni elemento rappresenta una classificazione e un elenco delle valutazioni corrispondenti a quella classificazione. Inizialmente, questa mappa viene popolata con valutazioni di cinque stelle e di una stella.

## Attributi di primo livello
<a name="Expressions.Attributes.TopLevelAttributes"></a>

Un attributo si definisce di *primo livello* se non è incorporato in un altro attributo. Per gli elementi `ProductCatalog`, gli attributi di primo livello sono:
+ `Id`
+ `Title`
+ `Description`
+ `BicycleType`
+ `Brand`
+ `Price`
+ `Color`
+ `ProductCategory`
+ `InStock`
+ `QuantityOnHand`
+ `RelatedItems`
+ `Pictures`
+ `ProductReviews`
+ `Comment`
+ `Safety.Warning`

Tutti questi attributi di primo livello sono scalari, eccetto `Color` (elenco), `RelatedItems` (elenco), `Pictures` (mappa) e `ProductReviews` (mappa).

## Attributi nidificati
<a name="Expressions.Attributes.NestedAttributes"></a>

Un attributo si definisce *nidificato* se è incorporato in un altro attributo. Per ottenere l'accesso a un attributo nidificato, usa gli *operatori di deferenziazione*:
+ `[n]`: per gli elementi list
+ `.` (punto): per gli elementi map

### Accesso agli elementi dell'elenco
<a name="Expressions.Attributes.NestedElements.AccessingListElements"></a>

L'operatore di deferenziazione per un elemento dell'elenco è **[*N*]**, dove *n* è il numero dell'elemento. Gli elementi dell'elenco sono a base zero, ovvero [0] rappresenta il primo elemento nell'elenco, [1] il secondo e così via. Ecco alcuni esempi:
+ `MyList[0]`
+ `AnotherList[12]`
+ `ThisList[5][11]`

L'elemento `ThisList[5]` è esso stesso un elenco nidificato. Pertanto, `ThisList[5][11]` si riferisce al dodicesimo elemento in quell'elenco.

Il numero all'interno delle parentesi quadre deve essere un numero intero non negativo. Pertanto, le espressioni seguenti non sono valide:
+ `MyList[-1]`
+ `MyList[0.4]`

### Accesso agli elementi della mappa
<a name="Expressions.Attributes.NestedElements.AccessingMapElements"></a>

L'operatore di deferenziazione per una mappa è **.** (un punto). Usa un punto come separatore tra gli elementi in una mappa:
+ `MyMap.nestedField`
+ `MyMap.nestedField.deeplyNestedField`

## Percorsi dei documenti
<a name="Expressions.Attributes.NestedElements.DocumentPathExamples"></a>

In un espressione si utilizza un *percorso del documento* per comunicare a DynamoDB dove trovare un attributo. Per gli attributi di primo livello, il percorso del documento è semplicemente il nome dell'attributo. Per un attributo nidificato, costruisci il percorso del documento usando gli operatori di deferenziazione.

Di seguito sono riportati alcuni esempi di percorsi di documenti. (Fai riferimento all'elemento mostrato in [Riferimento agli attributi degli elementi quando si utilizzano le espressioni in DynamoDB](#Expressions.Attributes)).
+ Un attributo scalare di primo livello:

   `Description`
+ Un attributo dell'elenco di primo livello. (Questo restituisce l'intero elenco, non solo alcuni elementi).

  `RelatedItems`
+ Il terzo elemento dall'elenco `RelatedItems`. (Ricorda che gli elementi dell'elenco sono a base zero).

  `RelatedItems[2]`
+ L'immagine di vista frontale del prodotto.

  `Pictures.FrontView`
+ Tutte le valutazioni da cinque stelle.

  `ProductReviews.FiveStar`
+ La prima delle valutazioni da cinque stelle.

  `ProductReviews.FiveStar[0]`

**Nota**  
La profondità massima per un percorso del documento è 32. Pertanto, il numero di operatori di deferenziazione in un percorso non può eccedere questo limite.

È possibile utilizzare qualsiasi nome di attributo nel percorso di un documento purché soddisfi i seguenti requisiti:
+ Il primo carattere è una lettera (`a-z` o `A-Z`) o un numero (`0-9`)
+ Il secondo carattere (se presente) è una lettera (`a-z` o `A-Z`)

**Nota**  
Se un nome di attributo non soddisfa questo requisito, devi definire un nome di attributo dell'espressione come un segnaposto.

Per ulteriori informazioni, consulta [Nomi di attributi di espressione (alias) in DynamoDB](Expressions.ExpressionAttributeNames.md).

# Nomi di attributi di espressione (alias) in DynamoDB
<a name="Expressions.ExpressionAttributeNames"></a>

Un *nome di attributo di espressione* è un alias (o segnaposto) utilizzato in un’espressione Amazon DynamoDB in alternativa a un nome di attributo effettivo. Un nome di attributo di espressione deve iniziare con un simbolo di cancelletto (`#`) ed essere seguito da uno o più caratteri alfanumerici. È consentito anche il carattere trattino basso (`_`).

In questa sezione vengono descritte diverse situazioni in cui è necessario utilizzare i nomi di attributi di espressione.

**Nota**  
Gli esempi in questa sezione utilizzano il AWS Command Line Interface (AWS CLI). 

**Topics**
+ [

## Parole riservate
](#Expressions.ExpressionAttributeNames.ReservedWords)
+ [

## Nomi di attributi contenenti caratteri speciali
](#Expressions.ExpressionAttributeNames.AttributeNamesContainingSpecialCharacters)
+ [

## Attributi nidificati
](#Expressions.ExpressionAttributeNames.NestedAttributes)
+ [

## Riferimento ripetuto ai nomi di attributo
](#Expressions.ExpressionAttributeNames.RepeatingAttributeNames)

## Parole riservate
<a name="Expressions.ExpressionAttributeNames.ReservedWords"></a>

A volte potrebbe essere necessario scrivere un'espressione contenente un nome di attributo in conflitto con una parola riservata di DynamoDB. Per un elenco completo delle parole riservate, consulta [Parole riservate in DynamoDB](ReservedWords.md).)

Ad esempio, l' AWS CLI esempio seguente non riuscirà perché `COMMENT` è una parola riservata.

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "Comment"
```

Come soluzione alternativa, puoi sostituire `Comment` con un nome di attributo di espressione come `#c`. Il simbolo `#` (cancelletto) è obbligatorio e indica che si tratta di un segnaposto per un nome di attributo. L' AWS CLI esempio sarebbe ora simile al seguente.

```
aws dynamodb get-item \
     --table-name ProductCatalog \
     --key '{"Id":{"N":"123"}}' \
     --projection-expression "#c" \
     --expression-attribute-names '{"#c":"Comment"}'
```

**Nota**  
Se un nome di attributo inizia con un numero, contiene uno spazio o una parola riservata, è *necessario* utilizzare un nome di attributo di espressione per sostituire il nome di tale attributo nell'espressione.

## Nomi di attributi contenenti caratteri speciali
<a name="Expressions.ExpressionAttributeNames.AttributeNamesContainingSpecialCharacters"></a>

Un punto (".") in un'espressione viene interpretato come carattere separatore in un percorso di un documento. Tuttavia, DynamoDB consente anche di utilizzare un punto e altri caratteri speciali, ad esempio, un trattino ("-") come parte di un nome di attributo. In alcuni casi questo può portare ad ambiguità. A titolo illustrativo, supponi di voler recuperare l'attributo `Safety.Warning` da un elemento `ProductCatalog` (consulta [Riferimento agli attributi degli elementi quando si utilizzano le espressioni in DynamoDB](Expressions.Attributes.md)).

Supponi di voler accedere a `Safety.Warning` utilizzando un'espressione di proiezione.

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "Safety.Warning"
```

DynamoDB restituisce un risultato vuoto, anziché la stringa prevista ("`Always wear a helmet`"). Ciò accade poiché DynamoDB interpreta un punto in un'espressione come separatore del percorso di un documento. In questo caso, occorre definire un nome di attributo di espressione (ad esempio `#sw`) come sostituto di `Safety.Warning`. Puoi quindi utilizzare l'espressione di proiezione seguente.

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "#sw" \
    --expression-attribute-names '{"#sw":"Safety.Warning"}'
```

DynamoDB restituirebbe quindi il risultato corretto.

**Nota**  
Se il nome di un attributo contiene un punto (".") o un trattino ("-"), è *necessario* utilizzare un nome di attributo di espressione per sostituire il nome di tale attributo nell'espressione.

## Attributi nidificati
<a name="Expressions.ExpressionAttributeNames.NestedAttributes"></a>

Si supponga di voler accedere all’attributo annidato `ProductReviews.OneStar`. In un nome di attributo di espressione, DynamoDB considera il punto (“.”) come carattere all’interno di un nome di attributo. Per fare riferimento all’attributo annidato, definisci un nome di attributo di espressione per ogni elemento nel percorso del documento:
+ `#pr — ProductReviews`
+ `#1star — OneStar`

Puoi quindi utilizzare `#pr.#1star` per l'espressione di proiezione.

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "#pr.#1star"  \
    --expression-attribute-names '{"#pr":"ProductReviews", "#1star":"OneStar"}'
```

DynamoDB restituirebbe quindi il risultato corretto.

## Riferimento ripetuto ai nomi di attributo
<a name="Expressions.ExpressionAttributeNames.RepeatingAttributeNames"></a>

I nomi di attributo di espressione sono utili quando si vuole fare riferimento ripetutamente allo stesso nome di attributo. Ad esempio, considera la seguente espressione per recuperare alcune valutazioni da un elemento di `ProductCatalog`.

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "ProductReviews.FiveStar, ProductReviews.ThreeStar, ProductReviews.OneStar"
```

Per renderlo più conciso, puoi sostituire `ProductReviews` con un nome di attributo di espressione come `#pr`. L'aspetto dell'espressione rivista è ora simile al seguente.
+  `#pr.FiveStar, #pr.ThreeStar, #pr.OneStar` 

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "#pr.FiveStar, #pr.ThreeStar, #pr.OneStar" \
    --expression-attribute-names '{"#pr":"ProductReviews"}'
```

Se definisci un nome di attributo di espressione, è necessario usarlo in maniera uniforme nell'intera espressione. Inoltre, non puoi omettere il simbolo `#`. 

# Utilizzo dei valori degli attributi di espressione in DynamoDB
<a name="Expressions.ExpressionAttributeValues"></a>

I *valori degli attributi di espressione* in Amazon DynamoDB agiscono come variabili. Sostituiscono i valori effettivi che si desidera confrontare, valori che potrebbero non essere noti fino al runtime. Un valore dell'attributo dell'espressione deve iniziare con un carattere di due punti (`:`) ed essere seguito da uno o più caratteri alfanumerici.

Per esempio, supponi di voler restituire tutti gli elementi `ProductCatalog` che sono disponibili in `Black` e che costano `500` o meno. Puoi utilizzare un'operazione `Scan` con un'espressione di filtro, come in questo esempio di AWS Command Line Interface (AWS CLI).

```
aws dynamodb scan \
    --table-name ProductCatalog \
    --filter-expression "contains(Color, :c) and Price <= :p" \
    --expression-attribute-values file://values.json
```

Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `values.json`:

```
{
    ":c": { "S": "Black" },
    ":p": { "N": "500" }
}
```

Se definisci un valore dell'attributo dell'espressione, è necessario usarlo in maniera uniforme nell'intera espressione. Inoltre, non puoi omettere il simbolo `:`. 

I valori degli attributi dell'espressione sono usati con espressioni di condizione della chiave, espressioni di condizioni, espressioni di aggiornamento ed espressioni di filtro.

# Utilizzo di espressioni di proiezione in DynamoDB
<a name="Expressions.ProjectionExpressions"></a>

Per leggere i dati da una tabella, vengono utilizzate operazioni quali `GetItem`, `Query` oppure `Scan`. Amazon DynamoDB restituisce tutti gli attributi dell'elemento per impostazione predefinita. Per ottenerne solo alcuni degli attributi e non tutti, usa un'espressione di proiezione.

Un'*espressione di proiezione* è una stringa che identifica gli attributi che desideri. Per recuperare un singolo attributo, specificane il nome. Per più attributi, i nomi devono essere separati da una virgola.

Di seguito sono riportati alcuni esempi di espressioni di proiezione basate sull'elemento `ProductCatalog` da [Riferimento agli attributi degli elementi quando si utilizzano le espressioni in DynamoDB](Expressions.Attributes.md):
+ Un singolo attributo di primo livello.

  `Title `
+ Tre attributi di livello superiore DynamoDB recupera l'intero set `Color`.

  `Title, Price, Color`
+ Quattro attributi di livello superiore. DynamoDB restituisce l'intero contenuto di `RelatedItems` e `ProductReviews`.

  `Title, Description, RelatedItems, ProductReviews`

**Nota**  
L’espressione di proiezione non ha alcun effetto sul consumo di throughput allocato. DynamoDB determina le unità di capacità utilizzate in base alla dimensione dell’elemento anziché alla quantità di dati restituiti a un’applicazione.

**Parole riservate e caratteri speciali**

DynamoDB dispone di parole riservate e caratteri speciali. DynamoDB consente di utilizzare le parole riservate e i caratteri speciali per i nomi, ma si consiglia di evitare questa opzione perché comporta l’utilizzo di alias per i nomi ogni volta che questi vengono utilizzati in un’espressione. Per un elenco completo, consulta [Parole riservate in DynamoDB](ReservedWords.md).

Sarà necessario utilizzare i nomi degli attributi di espressione al posto del nome effettivo se: 
+ Il nome di attributo è nell’elenco di parole riservate in DynamoDB.
+ Il nome dell’attributo non soddisfa il requisito che il primo carattere sia `a-z` o `A-Z` e che il secondo carattere (se presente) sia `a-Z`, `A-Z` o`0-9`.
+ Il nome dell’attributo contiene un **\$1** (cancelletto) o **:** (due punti).

L' AWS CLI esempio seguente mostra come utilizzare un'espressione di proiezione con un'`GetItem`operazione. Questa espressione di proiezione recupera un attributo scalare di primo livello (`Description`), il primo elemento in un elenco (`RelatedItems[0]`) e un elenco nidificato in una mappa (`ProductReviews.FiveStar`).

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '"Id": { "N": "123" } \
    --projection-expression "Description, RelatedItems[0], ProductReviews.FiveStar"
```

Per questo esempio viene restituito il seguente JSON.

```
{
    "Item": {
        "Description": {
            "S": "123 description"
        },
        "ProductReviews": {
            "M": {
                "FiveStar": {
                    "L": [
                        {
                            "S": "Excellent! Can't recommend it highly enough! Buy it!"
                        },
                        {
                            "S": "Do yourself a favor and buy this."
                        }
                    ]
                }
            }
        },
        "RelatedItems": {
            "L": [
                {
                    "N": "341"
                }
            ]
        }
    }
}
```

# Utilizzo di espressioni di aggiornamento in DynamoDB
<a name="Expressions.UpdateExpressions"></a>

L'operazione `UpdateItem` aggiorna una voce esistente o aggiunge una nuova voce alla tabella, se non è già presente. È necessario fornire la chiave dell'elemento che intendi aggiornare. È necessario fornire inoltre un'espressione di aggiornamento che indica gli attributi che intendi modificare e i valori che intendi assegnargli. 

Una *espressione di aggiornamento* specifica come `UpdateItem` modificherà gli attributi di un elemento, ad esempio impostando un valore scalare o rimuovendo elementi da un elenco o da una mappa.

Di seguito è riportato un riepilogo della sintassi delle espressioni di aggiornamento.

```
update-expression ::=
    [ SET action [, action] ... ]
    [ REMOVE action [, action] ...]
    [ ADD action [, action] ... ]
    [ DELETE action [, action] ...]
```

Un'espressione di aggiornamento comprende una o più clausole. Ogni clausola inizia con una parola chiave `SET`, `REMOVE`, `ADD` o `DELETE`. Puoi includere qualsiasi di queste clausole in un'espressione di aggiornamento, in qualsiasi ordine. Tuttavia, ciascuna parola chiave dell'operazione può comparire una sola volta.

All'interno di ogni clausola esistono una o più operazioni separate da virgole. Ciascuna operazione rappresenta una modifica di dati.

Gli esempi in questa sezione si basano sull'elemento `ProductCatalog` illustrato in [Utilizzo di espressioni di proiezione in DynamoDB](Expressions.ProjectionExpressions.md).

Gli argomenti seguenti illustrano diversi casi d'uso dell'operazione `SET`.

**Topics**
+ [

## SET: modifica o aggiunta di attributi dell'elemento
](#Expressions.UpdateExpressions.SET)
+ [

## REMOVE: eliminazione degli attributi da un elemento
](#Expressions.UpdateExpressions.REMOVE)
+ [

## ADD: aggiornamento di numeri e set
](#Expressions.UpdateExpressions.ADD)
+ [

## DELETE: rimozione di elementi da un set
](#Expressions.UpdateExpressions.DELETE)
+ [

## Utilizzo di più espressioni di aggiornamento
](#Expressions.UpdateExpressions.Multiple)

## SET: modifica o aggiunta di attributi dell'elemento
<a name="Expressions.UpdateExpressions.SET"></a>

Utilizza l'operazione `SET` in un'espressione di aggiornamento per aggiungere uno o più attributi a un elemento. Se alcuni di questi attributi esistono già, vengono sovrascritti dai nuovi valori. Se intendi evitare la sovrascrittura di un attributo esistente, puoi utilizzare `SET` con la funzione `if_not_exists`. La funzione `if_not_exists` è specifica dell'operazione `SET` e può essere utilizzata solo in un'espressione di aggiornamento.

Quando utilizzi `SET` per aggiornare un elemento dell'elenco, i contenuti dell'elemento vengono sostituiti con i nuovi dati specificati. Se l'elemento non esiste ancora, `SET` aggiunge il nuovo elemento alla fine dell'elenco.

Se aggiungi più elementi in un'unica operazione `SET`, gli elementi verranno ordinati per numero di elemento.

Puoi inoltre utilizzare `SET` per aggiungere o sottrarre un attributo di tipo `Number`. Per eseguire più operazioni `SET`, separarle con virgole.

Nel riepilogo della sintassi seguente:
+ L'*path*elemento è il percorso del documento verso l'elemento.
+ Un **operand**elemento può essere il percorso del documento verso un elemento o una funzione.

```
set-action ::=
    path = value

value ::=
    operand
    | operand '+' operand
    | operand '-' operand

operand ::=
    path | function

function ::=
    if_not_exists (path, value)
```

Se l’elemento non contiene un attributo nel percorso specificato, `if_not_exists` restituisce `value`. Altrimenti, restituisce `path`.

L'operazione `PutItem` seguente crea un elemento di esempio a cui gli esempi fanno riferimento.

```
aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json
```

Gli argomenti per `--item` sono memorizzati nel file `item.json`: (Per semplicità, vengono utilizzati solo pochi attributi dell'item).

```
{
    "Id": {"N": "789"},
    "ProductCategory": {"S": "Home Improvement"},
    "Price": {"N": "52"},
    "InStock": {"BOOL": true},
    "Brand": {"S": "Acme"}
}
```

**Topics**
+ [

### Modifica degli attributi
](#Expressions.UpdateExpressions.SET.ModifyingAttributes)
+ [

### Aggiunta di elenchi e mappe
](#Expressions.UpdateExpressions.SET.AddingListsAndMaps)
+ [

### Aggiunta di elementi a un elenco
](#Expressions.UpdateExpressions.SET.AddingListElements)
+ [

### Aggiunta di attributi di mappa nidificati
](#Expressions.UpdateExpressions.SET.AddingNestedMapAttributes)
+ [

### Incremento e decremento di attributi numerici
](#Expressions.UpdateExpressions.SET.IncrementAndDecrement)
+ [

### Aggiunta di elementi a un elenco
](#Expressions.UpdateExpressions.SET.UpdatingListElements)
+ [

### Prevenzione delle sovrascritture di un attributo esistente
](#Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites)

### Modifica degli attributi
<a name="Expressions.UpdateExpressions.SET.ModifyingAttributes"></a>

**Example**  
Aggiorna gli attributi `ProductCategory` e `Price`.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET ProductCategory = :c, Price = :p" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `values.json`:  

```
{
    ":c": { "S": "Hardware" },
    ":p": { "N": "60" }
}
```

**Nota**  
Nell'operazione `UpdateItem`, `--return-values ALL_NEW` fa in modo che DynamoDB restituisca l'elemento come compare dopo l'aggiornamento.

### Aggiunta di elenchi e mappe
<a name="Expressions.UpdateExpressions.SET.AddingListsAndMaps"></a>

**Example**  
Aggiungi un nuovo elenco e una nuova mappa.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems = :ri, ProductReviews = :pr" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `values.json`:  

```
{
    ":ri": {
        "L": [
            { "S": "Hammer" }
        ]
    },
    ":pr": {
        "M": {
            "FiveStar": {
                "L": [
                    { "S": "Best product ever!" }
                ]
            }
        }
    }
}
```

### Aggiunta di elementi a un elenco
<a name="Expressions.UpdateExpressions.SET.AddingListElements"></a>

**Example**  
Aggiungi un nuovo attributo all'elenco `RelatedItems`. Ricorda che gli elementi dell'elenco sono a base zero, ovvero [0] rappresenta il primo elemento nell'elenco, [1] il secondo e così via.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems[1] = :ri" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `values.json`:  

```
{
    ":ri": { "S": "Nails" }
}
```

**Nota**  
Quando utilizzi `SET` per aggiornare un elemento dell'elenco, i contenuti dell'elemento vengono sostituiti con i nuovi dati specificati. Se l'elemento non esiste ancora, `SET` aggiunge il nuovo elemento alla fine dell'elenco.  
Se aggiungi più elementi in un'unica operazione `SET`, gli elementi verranno ordinati per numero di elemento.

### Aggiunta di attributi di mappa nidificati
<a name="Expressions.UpdateExpressions.SET.AddingNestedMapAttributes"></a>

**Example**  
Aggiungi alcuni attributi di mappa nidificati.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #pr.#5star[1] = :r5, #pr.#3star = :r3" \
    --expression-attribute-names file://names.json \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Gli argomenti per `--expression-attribute-names` sono memorizzati nel file `names.json`:  

```
{
    "#pr": "ProductReviews",
    "#5star": "FiveStar",
    "#3star": "ThreeStar"
}
```
Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `values.json`:  

```
{
    ":r5": { "S": "Very happy with my purchase" },
    ":r3": {
        "L": [
            { "S": "Just OK - not that great" }
        ]
    }
}
```

**Importante**  
Non è possibile aggiornare gli attributi della mappa annidata se la mappa principale non esiste. Se si tenta di aggiornare un attributo annidato (ad esempio,`ProductReviews.FiveStar`) quando la mappa principale (`ProductReviews`) non esiste, DynamoDB restituisce `ValidationException` un con il *messaggio «Il percorso del documento fornito nell'espressione di aggiornamento non è valido per l'aggiornamento*».  
Quando crei elementi che avranno gli attributi della mappa nidificata aggiornati in un secondo momento, inizializza mappe vuote per gli attributi principali. Esempio:  

```
{
    "Id": {"N": "789"},
    "ProductReviews": {"M": {}},
    "Metadata": {"M": {}}
}
```
Ciò consente di aggiornare gli attributi annidati senza errori. `ProductReviews.FiveStar`

### Incremento e decremento di attributi numerici
<a name="Expressions.UpdateExpressions.SET.IncrementAndDecrement"></a>

Puoi eseguire aggiunte o sottrazioni da un attributo numerico esistente. A questo scopo, utilizza gli operatori `+` (più) e `-` (meno).

**Example**  
Riduci il valore `Price` di un elemento.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = Price - :p" \
    --expression-attribute-values '{":p": {"N":"15"}}' \
    --return-values ALL_NEW
```
Per aumentare il valore `Price`, puoi utilizzare l'operatore `+` nell'espressione di aggiornamento.

### Aggiunta di elementi a un elenco
<a name="Expressions.UpdateExpressions.SET.UpdatingListElements"></a>

Puoi aggiungere elementi alla fine di un elenco. A tale scopo, utilizza `SET` con la funzione `list_append`. Il nome funzione rileva la distinzione tra maiuscole e minuscole. La funzione `list_append` è specifica dell'operazione `SET` e può essere utilizzata solo in un'espressione di aggiornamento. La sintassi è esposta di seguito.
+ `list_append (list1, list2)`

La funzione prende due liste come input e aggiunge tutti gli elementi da `list2` a ` list1`.

**Example**  
In [Aggiunta di elementi a un elenco](#Expressions.UpdateExpressions.SET.AddingListElements), viene creato l'elenco `RelatedItems` e popolato con due elementi: `Hammer` e `Nails`. Vengono quindi aggiunti due altri elementi alla fine di `RelatedItems`.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #ri = list_append(#ri, :vals)" \
    --expression-attribute-names '{"#ri": "RelatedItems"}' \
    --expression-attribute-values file://values.json  \
    --return-values ALL_NEW
```
Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `values.json`:  

```
{
    ":vals": {
        "L": [
            { "S": "Screwdriver" },
            {"S": "Hacksaw" }
        ]
    }
}
```
Infine, viene aggiunto un ulteriore elemento all'*inizio* di `RelatedItems`. A questo scopo, scambia l'ordine degli elementi `list_append`. Ricorda che `list_append` accetta due elenchi come input e aggiunge il secondo elenco al primo.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #ri = list_append(:vals, #ri)" \
    --expression-attribute-names '{"#ri": "RelatedItems"}' \
    --expression-attribute-values '{":vals": {"L": [ { "S": "Chisel" }]}}' \
    --return-values ALL_NEW
```
L'attributo `RelatedItems` risultante contiene ora cinque elementi nell'ordine seguente: `Chisel`, `Hammer`, `Nails`, `Screwdriver`, `Hacksaw`.

### Prevenzione delle sovrascritture di un attributo esistente
<a name="Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites"></a>

**Example**  
Imposta l'attributo `Price` di un elemento, ma solo se l'elemento non dispone già di un attributo `Price`. Se l'attributo `Price` esiste già, non accade nulla.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = if_not_exists(Price, :p)" \
    --expression-attribute-values '{":p": {"N": "100"}}' \
    --return-values ALL_NEW
```

## REMOVE: eliminazione degli attributi da un elemento
<a name="Expressions.UpdateExpressions.REMOVE"></a>

Utilizza l'operazione `REMOVE` in una espressione di aggiornamento per rimuovere uno o più attributi di un elemento in Amazon DynamoDB. Per eseguire più operazioni `REMOVE`, separarle con virgole.

Di seguito è riportato un riepilogo della sintassi di `REMOVE` in un'espressione di aggiornamento. L'unico operando è il percorso di documento dell'attributo che intendi rimuovere.

```
remove-action ::=
    path
```

**Example**  
Rimuovi alcuni attributi di un elemento. Se gli attributi non esistono, non accade nulla.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "REMOVE Brand, InStock, QuantityOnHand" \
    --return-values ALL_NEW
```

### Rimozione di elementi da un elenco
<a name="Expressions.UpdateExpressions.REMOVE.RemovingListElements"></a>

Puoi utilizzare `REMOVE` per eliminare singoli elementi da un elenco.

**Example**  
In [Aggiunta di elementi a un elenco](#Expressions.UpdateExpressions.SET.UpdatingListElements), modifica un attributo di elenco (`RelatedItems`) in modo che contenga cinque elementi:   
+ `[0]`—`Chisel`
+ `[1]`—`Hammer`
+ `[2]`—`Nails`
+ `[3]`—`Screwdriver`
+ `[4]`—`Hacksaw`
L'esempio seguente AWS Command Line Interface (AWS CLI) elimina `Hammer` e `Nails` dall'elenco.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "REMOVE RelatedItems[1], RelatedItems[2]" \
    --return-values ALL_NEW
```
Dopo che `Hammer` e `Nails` sono stati rimossi, gli elementi rimanenti vengono spostati. Ora l'elenco contiene quanto segue:  
+ `[0]`—`Chisel`
+ `[1]`—`Screwdriver`
+ `[2]`—`Hacksaw`

## ADD: aggiornamento di numeri e set
<a name="Expressions.UpdateExpressions.ADD"></a>

**Nota**  
In generale, consigliamo di utilizzare `SET` piuttosto che `ADD` garantire operazioni idempotenti.

Utilizza l'operazione `ADD` in un'espressione di aggiornamento per aggiungere un nuovo attributo e i suoi valori a un elemento.

Se l'attributo esiste già, il comportamento di `ADD` dipende dal tipo di dati dell'attributo:
+ Se l'attributo è un numero e anche il valore da aggiungere è un numero, il valore viene aggiunto matematicamente all'attributo esistente. Se il valore è un numero negativo, viene sottratto dall'attributo esistente.
+ Se l'attributo è un set e anche il valore da aggiungere è un set, il valore viene aggiunto matematicamente al set esistente.

**Nota**  
L'operazione `ADD` supporta solo i tipi di dati Number e Set.

Per eseguire più operazioni `ADD`, separarle con virgole.

Nel riepilogo della sintassi seguente:
+ L'*path*elemento è il percorso del documento verso un attributo. L'attributo deve essere un tipo di dati `Number` o Set. 
+ L'*value*elemento è un numero che si desidera aggiungere all'attributo (per `Number` i tipi di dati) o un set da aggiungere all'attributo (per i tipi di set).

```
add-action ::=
    path value
```

Gli argomenti seguenti illustrano diversi casi d'uso dell'operazione `ADD`.

**Topics**
+ [

### Aggiunta di un numero
](#Expressions.UpdateExpressions.ADD.Number)
+ [

### Aggiunta di elementi a un set
](#Expressions.UpdateExpressions.ADD.Set)

### Aggiunta di un numero
<a name="Expressions.UpdateExpressions.ADD.Number"></a>

Supponiamo che l'attributo `QuantityOnHand` non esista. L' AWS CLI esempio seguente è impostato `QuantityOnHand` su 5.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD QuantityOnHand :q" \
    --expression-attribute-values '{":q": {"N": "5"}}' \
    --return-values ALL_NEW
```

Ora che `QuantityOnHand` esiste, puoi eseguire nuovamente l'esempio per incrementare `QuantityOnHand` ogni volta di 5.

### Aggiunta di elementi a un set
<a name="Expressions.UpdateExpressions.ADD.Set"></a>

Supponiamo che l'attributo `Color` non esista. L'esempio AWS CLI seguente imposta `Color` su un set di stringhe con due elementi.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD Color :c" \
    --expression-attribute-values '{":c": {"SS":["Orange", "Purple"]}}' \
    --return-values ALL_NEW
```

Ora che `Color` esiste, puoi aggiungergli più elementi:

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD Color :c" \
    --expression-attribute-values '{":c": {"SS":["Yellow", "Green", "Blue"]}}' \
    --return-values ALL_NEW
```

## DELETE: rimozione di elementi da un set
<a name="Expressions.UpdateExpressions.DELETE"></a>

**Importante**  
L'operazione `DELETE` supporta solo i tipi di dati `Set`.

Utilizza l'operazione `DELETE` in un'espressione di aggiornamento per rimuovere uno o più elementi da un set. Per eseguire più operazioni `DELETE`, separarle con virgole.

Nel riepilogo della sintassi seguente:
+ L'*path*elemento è il percorso del documento verso un attributo. L'attributo deve essere un tipo di dati Set.
+ *subset*È uno o più elementi da cui si desidera eliminare*path*. È necessario specificare *subset* come tipo di set.

```
delete-action ::=
    path subset
```

**Example**  
In [Aggiunta di elementi a un set](#Expressions.UpdateExpressions.ADD.Set), crea lo String Set `Color`. In questo esempio vengono rimossi alcuni elementi di tale set.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "DELETE Color :p" \
    --expression-attribute-values '{":p": {"SS": ["Yellow", "Purple"]}}' \
    --return-values ALL_NEW
```

## Utilizzo di più espressioni di aggiornamento
<a name="Expressions.UpdateExpressions.Multiple"></a>

È possibile utilizzare più azioni in una singola espressione di aggiornamento. Tutti i riferimenti agli attributi vengono risolti in base allo stato dell'elemento prima dell'applicazione di qualsiasi azione.

**Example**  
Dato un elemento`{"id": "1", "a": 1, "b": 2, "c": 3}`, l'espressione seguente rimuove `a` e sposta i valori di `b` e`c`:  

```
aws dynamodb update-item \
    --table-name test \
    --key '{"id":{"S":"1"}}' \
    --update-expression "REMOVE a SET b = a, c = b" \
    --return-values ALL_NEW
```
Il risultato è`{"id": "1", "b": 1, "c": 2}`. Anche se `a` viene rimosso e `b` riassegnato nella stessa espressione, entrambi i riferimenti tornano ai valori originali.

**Example**  
Se vuoi modificare il valore di un attributo e rimuovere completamente un altro attributo, puoi utilizzare le operazioni SET e REMOVE in una singola istruzione. Questa operazione imposta il valore di `Price` su 15 e rimuove l'attributo `InStock` dall'elemento.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = Price - :p REMOVE InStock" \
    --expression-attribute-values '{":p": {"N":"15"}}' \
    --return-values ALL_NEW
```

**Example**  
Se desideri aggiungere una voce a un elenco modificando anche il valore di un attributo, puoi utilizzare due operazioni SET in una singola istruzione. Questa operazione aggiunge "Nails" all'attributo di elenco `RelatedItems` e imposta il valore di `Price` su 21.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems[1] = :newValue, Price = :newPrice" \
    --expression-attribute-values '{":newValue": {"S":"Nails"}, ":newPrice": {"N":"21"}}'  \
    --return-values ALL_NEW
```

# Espressioni, operatori e funzioni di condizione e di filtro in DynamoDB
<a name="Expressions.OperatorsAndFunctions"></a>

Per manipolare i dati in una tabella DynamoDB, è possibile utilizzare le operazioni `PutItem`, `UpdateItem` e `DeleteItem`. Per le operazioni di manipolazione dei dati, puoi specificare un'espressione di condizione per determinare quale elemento deve essere modificato. Se l’espressione condizionale restituisce true, l’operazione ha esito positivo. In caso contrario, l'operazione non va a buon fine.

In questa sezione sono descritte le funzioni e le parole chiave integrate per scrivere espressioni di condizione ed espressioni di filtro in Amazon DynamoDB. Per informazioni più dettagliate sulle funzioni e sulla programmazione con DynamoDB, consulta [Programmazione con DynamoDB e AWS SDKs](Programming.md) e [DynamoDB API Reference](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/).

**Topics**
+ [

## Sintassi per le espressioni di filtro e condizioni
](#Expressions.OperatorsAndFunctions.Syntax)
+ [

## Realizzazione di confronti
](#Expressions.OperatorsAndFunctions.Comparators)
+ [

## Funzioni
](#Expressions.OperatorsAndFunctions.Functions)
+ [

## Valutazioni logiche
](#Expressions.OperatorsAndFunctions.LogicalEvaluations)
+ [

## Parentesi
](#Expressions.OperatorsAndFunctions.Parentheses)
+ [

## Priorità nelle condizioni
](#Expressions.OperatorsAndFunctions.Precedence)

## Sintassi per le espressioni di filtro e condizioni
<a name="Expressions.OperatorsAndFunctions.Syntax"></a>

Nel seguente riepilogo della sintassi, an *operand* può essere il seguente: 
+ Un nome di attributo di primo livello, ad esempio `Id`, `Title`, `Description` o `ProductCategory`
+ Un percorso di documento che fa riferimento a un attributo nidificato

```
condition-expression ::=
      operand comparator operand
    | operand BETWEEN operand AND operand
    | operand IN ( operand (',' operand (, ...) ))
    | function
    | condition AND condition
    | condition OR condition
    | NOT condition
    | ( condition )

comparator ::=
    =
    | <>
    | <
    | <=
    | >
    | >=

function ::=
    attribute_exists (path)
    | attribute_not_exists (path)
    | attribute_type (path, type)
    | begins_with (path, substr)
    | contains (path, operand)
    | size (path)
```

## Realizzazione di confronti
<a name="Expressions.OperatorsAndFunctions.Comparators"></a>

Utilizza questi comparatori per confrontare un operando con un singolo valore:
+ `a = b`— Vero se *a* è uguale a. *b*
+ `a <> b`— Vero se non *a* è uguale a*b*.
+ `a < b`— Vero se *a* è minore di*b*.
+ `a <= b`— Vero se *a* è minore o uguale a*b*.
+ `a > b`— Vero se *a* è maggiore di*b*.
+ `a >= b`— Vero se *a* è maggiore o uguale a*b*.

Utilizza le parole chiave `BETWEEN` e `IN` per confrontare un operando con un intervallo di valori o con un elenco enumerato di valori:
+ `a BETWEEN b AND c`— Vero se *a* è maggiore o uguale a *b* e minore o uguale a*c*.
+ `a IN (b, c, d) `— Vero se *a* è uguale a qualsiasi valore nell'elenco, ad esempio qualsiasi di *b**c*, o. *d* L'elenco può contenere fino a 100 valori separati da virgole.

## Funzioni
<a name="Expressions.OperatorsAndFunctions.Functions"></a>

Utilizza le seguenti funzioni per determinare se un attributo è presente in un elemento o per valutare il valore di un attributo. I nomi di funzione rispettano la distinzione tra lettere maiuscole e minuscole. Per un attributo nidificato, è necessario fornire l'intero percorso del documento.


****  

| Funzione | Description | 
| --- | --- | 
|  `attribute_exists (path)`  | True se l'elemento contiene l'attributo specificato da `path`. Esempio: Verifica se un elemento nella tabella `Product` ha un'immagine di vista laterale. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 
|  `attribute_not_exists (path)`  | True se l'attributo specificato da `path` non è presente nell'elemento. Esempio: Verifica se un elemento ha un attributo `Manufacturer`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 
|  `attribute_type (path, type)`  |  True se l'attributo del percorso specificato è di un particolare tipo di dato. Il parametro `type` deve essere uno dei seguenti: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) È necessario utilizzare un valore di attributo di espressione per il parametro `type`. Esempio: Verifica se l'attributo `QuantityOnHand` è del tipo List. In questo esempio, `:v_sub` è un segnaposto per la stringa `L`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) È necessario utilizzare un valore di attributo di espressione per il parametro `type`.   | 
|  `begins_with (path, substr)`  |  True se l'attributo specificato da `path` inizia con una particolare sottostringa. Esempio: Verifica se i primi caratteri dell'URL dell'immagine di vista frontale sono `http://`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) Il valore di attributo di espressione `:v_sub` è un segnaposto per `http://`.  | 
|  `contains (path, operand)`  | True se l'attributo specificato da `path` è uno dei seguenti: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) Se l'attributo specificato da `path` è `String`, `operand` deve essere `String`. Se l'attributo specificato da `path` è un `Set`, l'`operand` deve essere il tipo di elemento del set. Il percorso e l'operando devono essere distinti. Vale a dire, `contains (a, a)` restituisce un errore. Esempio: Verifica se l'attributo `Brand` contiene la sottostringa `Company`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) Il valore di attributo di espressione `:v_sub` è un segnaposto per `Company`. Esempio: Verifica se il prodotto è disponibile in rosso. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) Il valore di attributo di espressione `:v_sub` è un segnaposto per `Red`. | 
|  `size (path)`  | Restituisce un numero che rappresenta le dimensioni di un attributo. I seguenti sono tipi di dati validi per l'utilizzo con `size`.  Se l'attributo è di tipo `String`, `size`restituisce la lunghezza della stringa. Esempio: Verifica se la stringa `Brand` è inferiore o uguale a 20 caratteri. Il valore di attributo di espressione `:v_sub` è un segnaposto per `20`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  Se l'attributo è di tipo `Binary`, `size` restituisce il numero di byte nel valore attributo. Esempio: supponi che l'elemento `ProductCatalog` abbia un attributo di tipo binario denominato `VideoClip`, che contiene un breve video del prodotto in uso. L'espressione seguente verifica se `VideoClip` supera i 64.000 byte. Il valore di attributo di espressione `:v_sub` è un segnaposto per `64000`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  Se il tipo di dati dell'attributo è `Set`, `size` restituisce il numero di elementi nell'insieme.  Esempio: Verifica se il prodotto è disponibile in più di un colore. Il valore di attributo di espressione `:v_sub` è un segnaposto per `1`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  Se il tipo dell'attributo è `List` o `Map`, `size` restituisce il numero di elementi figlio. Esempio: Verifica se il numero di revisioni `OneStar` ha superato una certa soglia. Il valore di attributo di espressione `:v_sub` è un segnaposto per `3`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 

## Valutazioni logiche
<a name="Expressions.OperatorsAndFunctions.LogicalEvaluations"></a>

Utilizza le parole chiave `AND`, `OR` e `NOT` per eseguire valutazioni logiche. Nell'elenco seguente, *a* e *b* rappresentano le condizioni da valutare.
+ `a AND b`— Vero se *a* e *b* sono entrambi veri.
+ `a OR b`— Vero se una delle due *a* o *b* (o entrambe) sono vere.
+ `NOT a`— Vero se *a* è falso. Falso se *a* è vero.

Di seguito è riportato un esempio di codice di AND in un'operazione.

`dynamodb-local (*)> select * from exprtest where a > 3 and a < 5;`

## Parentesi
<a name="Expressions.OperatorsAndFunctions.Parentheses"></a>

Utilizza le parentesi per modificare la priorità di una valutazione logica. Ad esempio, supponiamo che le condizioni *a* e *b* siano vere e che tale condizione *c* sia falsa. La seguente espressione restituisce true:
+ `a OR b AND c`

Tuttavia, se racchiudi una condizione tra parentesi, verrà valutata per prima. Ad esempio, la seguente espressione restituisce false:
+  `(a OR b) AND c`

**Nota**  
Puoi annidare le parentesi in un'espressione: quelle più interne saranno valutate per prime.

Di seguito è riportato un esempio di codice con parentesi in una valutazione logica.

`dynamodb-local (*)> select * from exprtest where attribute_type(b, string) or ( a = 5 and c = “coffee”);`

## Priorità nelle condizioni
<a name="Expressions.OperatorsAndFunctions.Precedence"></a>

 DynamoDB valuta le condizioni da sinistra a destra utilizzando le seguenti regole di precedenza:
+ `= <> < <= > >=`
+ `IN`
+ `BETWEEN`
+ `attribute_exists attribute_not_exists begins_with contains`
+ Parentesi
+ `NOT`
+ `AND`
+ `OR`

# Esempio di CLI di espressione condizionale in DynamoDB
<a name="Expressions.ConditionExpressions"></a>

Di seguito sono riportati alcuni AWS Command Line Interface (AWS CLI) esempi di utilizzo delle espressioni condizionali. Questo esempi sono basati sulla tabella `ProductCatalog`, che è stata introdotta in [Riferimento agli attributi degli elementi quando si utilizzano le espressioni in DynamoDB](Expressions.Attributes.md). La chiave di partizione di questa tabella è `Id`; non è presente una chiave di ordinamento. L'operazione `PutItem` seguente crea un elemento `ProductCatalog` di esempio a cui gli esempi fanno riferimento.

```
aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json
```

Gli argomenti per `--item` sono memorizzati nel file `item.json`: (Per semplicità, vengono utilizzati solo pochi attributi dell'item).

```
{
    "Id": {"N": "456" },
    "ProductCategory": {"S": "Sporting Goods" },
    "Price": {"N": "650" }
}
```

**Topics**
+ [

## Put condizionale
](#Expressions.ConditionExpressions.PreventingOverwrites)
+ [

## Eliminazioni condizionali
](#Expressions.ConditionExpressions.AdvancedComparisons)
+ [

## Aggiornamenti condizionali
](#Expressions.ConditionExpressions.SimpleComparisons)
+ [

## Esempi di espressioni condizionali
](#Expressions.ConditionExpressions.ConditionalExamples)

## Put condizionale
<a name="Expressions.ConditionExpressions.PreventingOverwrites"></a>

L'operazione `PutItem` sovrascrive un elemento con la stessa chiave primaria (se esiste). Se vuoi evitare che ciò accada, utilizza un'espressione di condizione. Ciò consente alla scrittura di procedere solo se l'elemento in questione non possiede già la stessa chiave primaria.

L'esempio seguente utilizza `attribute_not_exists()` per verificare se la chiave primaria esiste nella tabella prima di tentare l'operazione di scrittura. 

**Nota**  
Se la chiave primaria è composta sia da una chiave di partizione (PK) che da una chiave di ordinamento (SK), il parametro controllerà se `attribute_not_exists(pk)` E `attribute_not_exists(sk)` vengono considerati true o false come intera istruzione prima di tentare l’operazione di scrittura.

```
aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json \
    --condition-expression "attribute_not_exists(Id)"
```

Se l'espressione di condizione viene valutata false, D restituisce il seguente messaggio di errore: The conditional request failed (La richiesta condizionale ha avuto esito negativo).

**Nota**  
Per ulteriori informazioni su `attribute_not_exists` e altre funzioni, consulta [Espressioni, operatori e funzioni di condizione e di filtro in DynamoDB](Expressions.OperatorsAndFunctions.md).

## Eliminazioni condizionali
<a name="Expressions.ConditionExpressions.AdvancedComparisons"></a>

Per eseguire un'eliminazione condizionale, utilizza un'operazione `DeleteItem` con un'espressione di condizione. L'espressione di condizione deve restituire true affinché l'operazione abbia esito positivo; in caso contrario, ha esito negativo.

Si consideri l’elemento sopra definito.

Supponiamo che tu voglia eliminare l'elemento, ma solo alle seguenti condizioni:
+  il valore `ProductCategory` è "Sporting Goods" o "Gardening Supplies";
+  il valore `Price` è compreso tra 500 e 600.

Nell'esempio seguente si tenta di eliminare l'elemento:

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"456"}}' \
    --condition-expression "(ProductCategory IN (:cat1, :cat2)) and (Price between :lo and :hi)" \
    --expression-attribute-values file://values.json
```

Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `values.json`:

```
{
    ":cat1": {"S": "Sporting Goods"},
    ":cat2": {"S": "Gardening Supplies"},
    ":lo": {"N": "500"},
    ":hi": {"N": "600"}
}
```

**Nota**  
Nell'espressione di condizione, `:` (due punti) indica un *valore di attributo dell'espressione*, ovvero un segnaposto per un valore effettivo. Per ulteriori informazioni, consulta [Utilizzo dei valori degli attributi di espressione in DynamoDB](Expressions.ExpressionAttributeValues.md).  
Per ulteriori informazioni su `IN`, `AND` e altre parole chiave, consulta [Espressioni, operatori e funzioni di condizione e di filtro in DynamoDB](Expressions.OperatorsAndFunctions.md).

In questo esempio, il confronto `ProductCategory` viene valutato come true, ma il confronto `Price` viene valutato come false. Ciò fa sì che l'espressione di condizione venga valutata come false e che l'operazione `DeleteItem` abbia esito negativo.

## Aggiornamenti condizionali
<a name="Expressions.ConditionExpressions.SimpleComparisons"></a>

Per eseguire un aggiornamento condizionale, utilizza un'operazione `UpdateItem` con un'espressione di condizione. L'espressione di condizione deve restituire true affinché l'operazione abbia esito positivo; in caso contrario, ha esito negativo.

**Nota**  
`UpdateItem` supporta anche *espressioni di aggiornamento*, in cui si specificano le modifiche che intendi apportare a una voce. Per ulteriori informazioni, consulta [Utilizzo di espressioni di aggiornamento in DynamoDB](Expressions.UpdateExpressions.md).

Si supponga di iniziare con l’elemento mostrato sopra.

Nel seguente esempio viene eseguita un'operazione `UpdateItem`. Prova a ridurre il `Price` di un prodotto di 75, ma l'espressione della condizione impedisce l'aggiornamento se `Price` è minore o uguale a 500.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --update-expression "SET Price = Price - :discount" \
    --condition-expression "Price > :limit" \
    --expression-attribute-values file://values.json
```

Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `values.json`:

```
{
    ":discount": { "N": "75"},
    ":limit": {"N": "500"}
}
```

Se l'attributo `Price` iniziale è 650, l'operazione `UpdateItem` riduce `Price` a 575. Se esegui nuovamente l'operazione `UpdateItem`, il valore `Price` viene ridotto a 500. Se esegui l'operazione una terza volta, l'espressione di condizione restituisce false e l'aggiornamento ha esito negativo.

**Nota**  
Nell'espressione di condizione, `:` (due punti) indica un *valore di attributo dell'espressione*, ovvero un segnaposto per un valore effettivo. Per ulteriori informazioni, consulta [Utilizzo dei valori degli attributi di espressione in DynamoDB](Expressions.ExpressionAttributeValues.md).  
Per ulteriori informazioni su "*>*" e altri operatori, consulta [Espressioni, operatori e funzioni di condizione e di filtro in DynamoDB](Expressions.OperatorsAndFunctions.md).

## Esempi di espressioni condizionali
<a name="Expressions.ConditionExpressions.ConditionalExamples"></a>

Per ulteriori informazioni sulle funzioni utilizzate negli esempi seguenti, consulta [Espressioni, operatori e funzioni di condizione e di filtro in DynamoDB](Expressions.OperatorsAndFunctions.md). Per ulteriori informazioni su come specificare diversi tipi di attributo in un'espressione, consulta [Riferimento agli attributi degli elementi quando si utilizzano le espressioni in DynamoDB](Expressions.Attributes.md). 

### Verifica degli attributi in un elemento
<a name="Expressions.ConditionExpressions.CheckingForAttributes"></a>

Puoi verificare la presenza o l'assenza di qualsiasi attributo. Se l'espressione condizionale viene valutata a true, l'operazione ha esito positivo, altrimenti ha esito negativo.

Nel seguente esempio si utilizza `attribute_not_exists` per eliminare un prodotto solo se non possiede un attributo `Price`.

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "attribute_not_exists(Price)"
```

DynamoDB fornisce anche una funzione `attribute_exists`. Nel seguente esempio un prodotto viene eliminato solo se ha ricevuto recensioni negative.

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "attribute_exists(ProductReviews.OneStar)"
```

### Verifica del tipo di attributo
<a name="Expressions.ConditionExpressions.CheckingForAttributeType"></a>

Puoi controllare il tipo di dati di un valore di attributo utilizzando la funzione `attribute_type`. Se l'espressione condizionale viene valutata a true, l'operazione ha esito positivo, altrimenti ha esito negativo.

Nell'esempio seguente viene utilizzato `attribute_type` per eliminare un prodotto solo se ha un attributo `Color` di tipo String Set. 

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "attribute_type(Color, :v_sub)" \
    --expression-attribute-values file://expression-attribute-values.json
```

Gli argomenti per `--expression-attribute-values` sono memorizzati nel expression-attribute-values file.json.

```
{
    ":v_sub":{"S":"SS"}
}
```

### Verifica del valore iniziale della stringa
<a name="Expressions.ConditionExpressions.CheckingBeginsWith"></a>

Puoi verificare se un valore di attributo String inizia con una particolare sottostringa utilizzando la funzione `begins_with`. Se l'espressione condizionale viene valutata a true, l'operazione ha esito positivo, altrimenti ha esito negativo. 

Nell'esempio seguente viene utilizzato `begins_with` per eliminare un prodotto solo se l'elemento `FrontView` della mappa `Pictures` inizia con un valore specifico.

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "begins_with(Pictures.FrontView, :v_sub)" \
    --expression-attribute-values file://expression-attribute-values.json
```

Gli argomenti per `--expression-attribute-values` sono memorizzati nel file expression-attribute-values .json.

```
{
    ":v_sub":{"S":"http://"}
}
```

### Controllo di un elemento in un set
<a name="Expressions.ConditionExpressions.CheckingForContains"></a>

Puoi verificare la presenza di un elemento in un set o cercare una sottostringa all'interno di una stringa utilizzando la funzione `contains`. Se l'espressione condizionale viene valutata a true, l'operazione ha esito positivo, altrimenti ha esito negativo. 

Nell'esempio seguente viene utilizzato `contains` per eliminare un prodotto solo se il String Set `Color` ha un elemento con un valore specifico. 

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "contains(Color, :v_sub)" \
    --expression-attribute-values file://expression-attribute-values.json
```

Gli argomenti per `--expression-attribute-values` sono memorizzati nel file expression-attribute-values .json.

```
{
    ":v_sub":{"S":"Red"}
}
```

### Controllo della dimensione di un valore di attributo
<a name="Expressions.ConditionExpressions.CheckingForSize"></a>

Puoi verificare la dimensione di un valore di attributo utilizzando la funzione `size`. Se l'espressione condizionale viene valutata a true, l'operazione ha esito positivo, altrimenti ha esito negativo. 

Nell'esempio seguente viene utilizzato `size` per eliminare un prodotto solo se la dimensione dell'attributo `VideoClip` Binary è maggiore di `64000` byte. 

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "size(VideoClip) > :v_sub" \
    --expression-attribute-values file://expression-attribute-values.json
```

Gli argomenti per `--expression-attribute-values` sono memorizzati nel file expression-attribute-values .json.

```
{
    ":v_sub":{"N":"64000"}
}
```

# Utilizzo del Time to Live in DynamoDB
<a name="TTL"></a>

Il Time to Live (TTL) per DynamoDB è un metodo conveniente per eliminare elementi che non sono più pertinenti. Il TTL consente di definire un timestamp per elemento in modo da indicare quando un elemento non è più necessario. DynamoDB elimina automaticamente gli elementi scaduti entro pochi giorni dalla data di scadenza, senza utilizzare il throughput di scrittura. 

Per utilizzare il TTL, è necessario prima abilitarlo su una tabella e poi definire un attributo specifico per archiviare il timestamp di scadenza del TTL. Il timestamp deve essere archiviato come tipo [di dati Number](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes) nel [formato Unix epoch time](https://en.wikipedia.org/wiki/Unix_time) con la granularità dei secondi. Gli elementi con un attributo TTL diverso da un tipo Number vengono ignorati dal processo TTL. Ogni volta che un elemento viene creato o aggiornato, è possibile calcolare l’ora di scadenza e salvarla nell’attributo TTL.

Gli articoli con attributi TTL validi e scaduti possono essere eliminati dal sistema in qualsiasi momento, in genere entro pochi giorni dalla scadenza. È comunque possibile aggiornare gli elementi scaduti in attesa di eliminazione, come anche modificare o rimuovere i relativi attributi TTL. Durante l’aggiornamento di un elemento scaduto, si consiglia di utilizzare un’espressione condizionale per assicurarsi che l’elemento non sia stato successivamente eliminato. Utilizza le espressioni di filtro per rimuovere gli elementi scaduti dai risultati di [Scan](Scan.md#Scan.FilterExpression) e [Query](Query.FilterExpression.md).

Gli elementi eliminati funzionano in modo simile a quelli eliminati tramite le tipiche operazioni di eliminazione. Una volta eliminati, gli elementi entrano nei flussi DynamoDB come eliminazioni da parte del servizio anziché degli utenti e vengono rimossi dagli indici secondari locali e dagli indici secondari globali proprio come con le altre operazioni di eliminazione. 

Se si utilizzano le [Tabelle globali versione 2019.11.21 (Corrente)](GlobalTables.md) e si utilizza anche la funzionalità TTL, DynamoDB replica le eliminazioni TTL in tutte le tabelle di replica. L’eliminazione TTL iniziale non consuma unità di capacità di scrittura (WCU, Write Capacity Units) nella Regione in cui si verifica la scadenza del TTL. Tuttavia, l’eliminazione TTL replicata nelle tabelle di replica consuma una WCU replicata quando si utilizza la capacità con provisioning o la scrittura replicata quando si utilizza la modalità con capacità on demand in ciascuna delle Regioni di replica e verranno addebitati i costi applicabili.

Per ulteriori informazioni su TTL, consulta i seguenti argomenti:

**Topics**
+ [

# Abilitazione del Time to Live in DynamoDB
](time-to-live-ttl-how-to.md)
+ [

# Calcolo del Time to Live (TTL) in DynamoDB
](time-to-live-ttl-before-you-start.md)
+ [

# Utilizzo di elementi scaduti e Time to Live
](ttl-expired-items.md)

# Abilitazione del Time to Live in DynamoDB
<a name="time-to-live-ttl-how-to"></a>

**Nota**  
Per facilitare il debug e la verifica del corretto funzionamento della funzionalità del TTL, i valori forniti per l’elemento TTL vengono registrati in testo semplice nei log di diagnostica di DynamoDB.

Puoi abilitare il TTL nella console Amazon DynamoDB AWS Command Line Interface ,AWS CLI in () o utilizzando Amazon [DynamoDB API Reference con uno qualsiasi dei presunti](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/). AWS SDKs È necessaria circa un’ora per abilitare il TTL su tutte le partizioni.

## Abilita DynamoDB TTL utilizzando la console AWS
<a name="time-to-live-ttl-how-to-enable-console"></a>

1. Accedi Console di gestione AWS e apri la console DynamoDB all'indirizzo. [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)

1. Scegli **Tables (Tabelle)** e quindi seleziona la tabella da modificare.

1. Nella scheda **Impostazioni aggiuntive**, nella sezione **Time to Live (TTL)** seleziona **Attiva**.

1. Quando abiliti TTL su una tabella, DynamoDB richiede di indicare un determinato nome attributo ricercato dal servizio per determinare se un item è idoneo per la scadenza. Il nome dell’attributo TTL, mostrato di seguito, fa distinzione tra maiuscole e minuscole e deve corrispondere all’attributo definito nelle operazioni di lettura e scrittura. In caso di mancata corrispondenza, gli elementi scaduti non verranno eliminati. La ridenominazione dell’attributo TTL richiede di disabilitare il TTL, per poi riabilitarlo con il nuovo attributo. Una volta disabilitato, il TTL continuerà a elaborare le eliminazioni per circa 30 minuti. Il TTL deve essere riconfigurato sulle tabelle ripristinate.  
![\[Nome dell’attributo TTL con distinzione tra maiuscole e minuscole utilizzato da DynamoDB per determinare l’idoneità di un elemento alla scadenza.\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/images/EnableTTL-Settings.png)

1. (Facoltativo) È possibile eseguire un test simulando la data e l’ora della scadenza con la corrispondenza di alcuni elementi. Questo fornisce un elenco di esempio di elementi e conferma che esistono elementi contenenti il nome dell’attributo TTL fornito insieme alla scadenza.

Una volta abilitato il TTL, l’attributo TTL viene contrassegnato come **TTL** quando si visualizzano gli elementi nella console DynamoDB. Puoi visualizzare la data e l'ora di scadenza di un item passando il puntatore del mouse sull'attributo. 

## Abilitazione del TTL di DynamoDB tramite l’API
<a name="time-to-live-ttl-how-to-enable-api"></a>

------
#### [ Python ]

È possibile abilitare il TTL con codice, utilizzando l'operazione. [UpdateTimeToLive](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/update_time_to_live.html)

```
import boto3


def enable_ttl(table_name, ttl_attribute_name):
    """
    Enables TTL on DynamoDB table for a given attribute name
        on success, returns a status code of 200
        on error, throws an exception

    :param table_name: Name of the DynamoDB table
    :param ttl_attribute_name: The name of the TTL attribute being provided to the table.
    """
    try:
        dynamodb = boto3.client('dynamodb')

        # Enable TTL on an existing DynamoDB table
        response = dynamodb.update_time_to_live(
            TableName=table_name,
            TimeToLiveSpecification={
                'Enabled': True,
                'AttributeName': ttl_attribute_name
            }
        )

        # In the returned response, check for a successful status code.
        if response['ResponseMetadata']['HTTPStatusCode'] == 200:
            print("TTL has been enabled successfully.")
        else:
            print(f"Failed to enable TTL, status code {response['ResponseMetadata']['HTTPStatusCode']}")
    except Exception as ex:
        print("Couldn't enable TTL in table %s. Here's why: %s" % (table_name, ex))
        raise


# your values
enable_ttl('your-table-name', 'expirationDate')
```

È possibile confermare che il TTL è abilitato utilizzando l'[DescribeTimeToLive](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/describe_time_to_live.html)operazione, che descrive lo stato TTL su una tabella. Lo stato di `TimeToLive` è `ENABLED` o `DISABLED`.

```
# create a DynamoDB client
dynamodb = boto3.client('dynamodb')

# set the table name
table_name = 'YourTable'

# describe TTL
response = dynamodb.describe_time_to_live(TableName=table_name)
```

------
#### [ JavaScript ]

È possibile abilitare il TTL con codice utilizzando l'operazione. [UpdateTimeToLiveCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-client-dynamodb/Class/UpdateTimeToLiveCommand/)

```
import { DynamoDBClient, UpdateTimeToLiveCommand } from "@aws-sdk/client-dynamodb";

const enableTTL = async (tableName, ttlAttribute) => {

    const client = new DynamoDBClient({});

    const params = {
        TableName: tableName,
        TimeToLiveSpecification: {
            Enabled: true,
            AttributeName: ttlAttribute
        }
    };

    try {
        const response = await client.send(new UpdateTimeToLiveCommand(params));
        if (response.$metadata.httpStatusCode === 200) {
            console.log(`TTL enabled successfully for table ${tableName}, using attribute name ${ttlAttribute}.`);
        } else {
            console.log(`Failed to enable TTL for table ${tableName}, response object: ${response}`);
        }
        return response;
    } catch (e) {
        console.error(`Error enabling TTL: ${e}`);
        throw e;
    }
};

// call with your own values
enableTTL('ExampleTable', 'exampleTtlAttribute');
```

------

## Abilita Time to Live utilizzando il AWS CLI
<a name="time-to-live-ttl-how-to-enable-cli-sdk"></a>

1. Abilita TTL nella tabella `TTLExample`.

   ```
   aws dynamodb update-time-to-live --table-name TTLExample --time-to-live-specification "Enabled=true, AttributeName=ttl"
   ```

1. Descrivi TTL nella tabella `TTLExample`.

   ```
   aws dynamodb describe-time-to-live --table-name TTLExample
   {
       "TimeToLiveDescription": {
           "AttributeName": "ttl",
           "TimeToLiveStatus": "ENABLED"
       }
   }
   ```

1. Aggiungi un elemento alla tabella `TTLExample` con l'attributo Time to Live (TTL) impostato usando la shell BASH e la AWS CLI. 

   ```
   EXP=`date -d '+5 days' +%s`
   aws dynamodb put-item --table-name "TTLExample" --item '{"id": {"N": "1"}, "ttl": {"N": "'$EXP'"}}'
   ```

Questo esempio inizia con la data corrente e aggiunge 5 giorni per creare un periodo di scadenza. Il periodo di scadenza viene quindi convertito nel formato temporale epoch Unix per aggiungere infine un item nella tabella `TTLExample`. 

**Nota**  
 Un modo per impostare i valori di scadenza per il Time to Live (TTL) consiste nel calcolare il numero di secondi da aggiungere al periodo di scadenza. Ad esempio, 5 giorni sono 432.000 secondi. È tuttavia in genere preferibile scegliere come punto di partenza una data.

Ottenere l'ora corrente in formato epoch Unix è piuttosto semplice, come negli esempi seguenti.
+ Terminale Linux: `date +%s`
+ Python: `import time; int(time.time())`
+ Java: `System.currentTimeMillis() / 1000L`
+ JavaScript: `Math.floor(Date.now() / 1000)`

## Abilita DynamoDB TTL utilizzando CloudFormation
<a name="time-to-live-ttl-how-to-enable-cf"></a>

```
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  TTLExampleTable:
    Type: AWS::DynamoDB::Table
    Description: "A DynamoDB table with TTL Specification enabled"
    Properties:
      AttributeDefinitions:
        - AttributeName: "Album"
          AttributeType: "S"
        - AttributeName: "Artist"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "Album"
          KeyType: "HASH"
        - AttributeName: "Artist"
          KeyType: "RANGE"
      ProvisionedThroughput:
        ReadCapacityUnits: "5"
        WriteCapacityUnits: "5"
      TimeToLiveSpecification:
        AttributeName: "TTLExampleAttribute"
        Enabled: true
```

[Ulteriori dettagli sull'utilizzo del TTL all'interno dei CloudFormation modelli sono disponibili qui.](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-table-timetolivespecification.html)

# Calcolo del Time to Live (TTL) in DynamoDB
<a name="time-to-live-ttl-before-you-start"></a>

Un modo comune per implementare il TTL consiste nell’impostare una scadenza per gli elementi in base a quando sono stati creati o aggiornati l’ultima volta. Questa operazione è fattibile aggiungendo la scadenza ai timestamp `createdAt` e `updatedAt`. Ad esempio, il TTL per gli elementi appena creati può essere impostato su `createdAt` \$1 90 giorni. Quando l’elemento viene aggiornato, il TTL può essere ricalcolato a `updatedAt` \$1 90 giorni.

La scadenza calcolata deve essere in formato epoch, in secondi. Per essere considerato valido per la scadenza e l’eliminazione, il TTL non può essere passato da più di cinque anni. Se si utilizza un altro formato, i processi TTL ignorano l'item. Se imposti l'ora di scadenza su un periodo futuro in cui desideri che l'articolo scada, l'articolo scadrà dopo tale periodo. Ad esempio, supponiamo di aver impostato l'ora di scadenza su 1724241326 (ovvero lunedì 21 agosto 2024 11:55:26 (UTC)). L'articolo scade dopo l'ora specificata. Non esiste una durata TTL minima. È possibile impostare l'ora di scadenza su qualsiasi ora futura, ad esempio a 5 minuti dall'ora corrente. Tuttavia, DynamoDB in genere elimina gli articoli scaduti entro 48 ore dalla data di scadenza, non immediatamente dopo la scadenza dell'articolo.

**Topics**
+ [

## Creazione di un oggetto e impostazione del Time to Live
](#time-to-live-ttl-before-you-start-create)
+ [

## Aggiornamento di un elemento e del Time to Live
](#time-to-live-ttl-before-you-start-update)

## Creazione di un oggetto e impostazione del Time to Live
<a name="time-to-live-ttl-before-you-start-create"></a>

L’esempio seguente mostra come calcolare la scadenza durante la creazione di un nuovo elemento, utilizzando `expireAt` come nome dell’attributo TTL. Un’istruzione di assegnazione ottiene il momento corrente come variabile. Nell’esempio, la scadenza viene calcolata come a 90 giorni dal momento corrente. La scadenza viene quindi convertita in formato epoch e salvata come tipo di dati intero nell’attributo TTL.

Gli esempi di codice seguenti mostrano come creare un elemento con un valore TTL.

------
#### [ Java ]

**SDK per Java 2.x**  

```
package com.amazon.samplelib.ttl;

import com.amazon.samplelib.CodeSampleUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * Creates an item in a DynamoDB table with TTL attributes.
 * This class demonstrates how to add TTL expiration timestamps to DynamoDB items.
 */
public class CreateTTL {

    private static final String USAGE =
        """
            Usage:
                <tableName> <primaryKey> <sortKey> <region>
            Where:
                tableName - The Amazon DynamoDB table being queried.
                primaryKey - The name of the primary key. Also known as the hash or partition key.
                sortKey - The name of the sort key. Also known as the range attribute.
                region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1)
            """;
    private static final int DAYS_TO_EXPIRE = 90;
    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
    private static final String PRIMARY_KEY_ATTR = "primaryKey";
    private static final String SORT_KEY_ATTR = "sortKey";
    private static final String CREATION_DATE_ATTR = "creationDate";
    private static final String EXPIRE_AT_ATTR = "expireAt";
    private static final String SUCCESS_MESSAGE = "%s PutItem operation with TTL successful.";
    private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found.";

    private final DynamoDbClient dynamoDbClient;

    /**
     * Constructs a CreateTTL instance with the specified DynamoDB client.
     *
     * @param dynamoDbClient The DynamoDB client to use
     */
    public CreateTTL(final DynamoDbClient dynamoDbClient) {
        this.dynamoDbClient = dynamoDbClient;
    }

    /**
     * Constructs a CreateTTL with a default DynamoDB client.
     */
    public CreateTTL() {
        this.dynamoDbClient = null;
    }

    /**
     * Main method to demonstrate creating an item with TTL.
     *
     * @param args Command line arguments
     */
    public static void main(final String[] args) {
        try {
            int result = new CreateTTL().processArgs(args);
            System.exit(result);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

    /**
     * Process command line arguments and create an item with TTL.
     *
     * @param args Command line arguments
     * @return 0 if successful, non-zero otherwise
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     * @throws IllegalArgumentException If arguments are invalid
     */
    public int processArgs(final String[] args) {
        // Argument validation (remove or replace this line when reusing this code)
        CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE);

        final String tableName = args[0];
        final String primaryKey = args[1];
        final String sortKey = args[2];
        final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null)
            .map(Region::of)
            .orElse(Region.US_EAST_1);

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final CreateTTL createTTL = new CreateTTL(ddb);
            createTTL.createItemWithTTL(tableName, primaryKey, sortKey);
            return 0;
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * Creates an item in the specified table with TTL attributes.
     *
     * @param tableName The name of the table
     * @param primaryKeyValue The value for the primary key
     * @param sortKeyValue The value for the sort key
     * @return The response from the PutItem operation
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     */
    public PutItemResponse createItemWithTTL(
        final String tableName, final String primaryKeyValue, final String sortKeyValue) {
        // Get current time in epoch second format
        final long createDate = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = createDate + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        final Map<String, AttributeValue> itemMap = new HashMap<>();
        itemMap.put(
            PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build());
        itemMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build());
        itemMap.put(
            CREATION_DATE_ATTR,
            AttributeValue.builder().n(String.valueOf(createDate)).build());
        itemMap.put(
            EXPIRE_AT_ATTR,
            AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final PutItemRequest request =
            PutItemRequest.builder().tableName(tableName).item(itemMap).build();

        try {
            final PutItemResponse response = dynamoDbClient.putItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return response;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
}
```
+  *Per i dettagli sull'API, consulta la sezione API Reference. [PutItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/PutItem)AWS SDK for Java 2.x * 

------
#### [ JavaScript ]

**SDK per JavaScript (v3)**  

```
import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";

export function createDynamoDBItem(table_name, region, partition_key, sort_key) {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    // Get the current time in epoch second format
    const current_time = Math.floor(new Date().getTime() / 1000);

    // Calculate the expireAt time (90 days from now) in epoch second format
    const expire_at = Math.floor((new Date().getTime() + 90 * 24 * 60 * 60 * 1000) / 1000);

    // Create DynamoDB item
    const item = {
        'partitionKey': {'S': partition_key},
        'sortKey': {'S': sort_key},
        'createdAt': {'N': current_time.toString()},
        'expireAt': {'N': expire_at.toString()}
    };

    const putItemCommand = new PutItemCommand({
        TableName: table_name,
        Item: item,
        ProvisionedThroughput: {
            ReadCapacityUnits: 1,
            WriteCapacityUnits: 1,
        },
    });

    client.send(putItemCommand, function(err, data) {
        if (err) {
            console.log("Exception encountered when creating item %s, here's what happened: ", data, err);
            throw err;
        } else {
            console.log("Item created successfully: %s.", data);
            return data;
        }
    });
}

// Example usage (commented out for testing)
// createDynamoDBItem('your-table-name', 'us-east-1', 'your-partition-key-value', 'your-sort-key-value');
```
+  Per i dettagli sull'API, consulta la sezione *AWS SDK per JavaScript API [PutItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/PutItemCommand)Reference*. 

------
#### [ Python ]

**SDK per Python (Boto3)**  

```
from datetime import datetime, timedelta

import boto3


def create_dynamodb_item(table_name, region, primary_key, sort_key):
    """
    Creates a DynamoDB item with an attached expiry attribute.

    :param table_name: Table name for the boto3 resource to target when creating an item
    :param region: string representing the AWS region. Example: `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :return: Void (nothing)
    """
    try:
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Get the current time in epoch second format
        current_time = int(datetime.now().timestamp())

        # Calculate the expiration time (90 days from now) in epoch second format
        expiration_time = int((datetime.now() + timedelta(days=90)).timestamp())

        item = {
            "primaryKey": primary_key,
            "sortKey": sort_key,
            "creationDate": current_time,
            "expireAt": expiration_time,
        }
        response = table.put_item(Item=item)

        print("Item created successfully.")
        return response
    except Exception as e:
        print(f"Error creating item: {e}")
        raise e


# Use your own values
create_dynamodb_item(
    "your-table-name", "us-west-2", "your-partition-key-value", "your-sort-key-value"
)
```
+  Per i dettagli sull'API, consulta [PutItem AWS](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/PutItem)*SDK for Python (Boto3) API Reference*. 

------

## Aggiornamento di un elemento e del Time to Live
<a name="time-to-live-ttl-before-you-start-update"></a>

Questo esempio è una continuazione di quello della sezione [precedente](#time-to-live-ttl-before-you-start-create). La scadenza può essere ricalcolata se l’elemento viene aggiornato. L’esempio seguente ricalcola il timestamp `expireAt` in modo che corrisponda a 90 giorni dal momento corrente.

Gli esempi di codice seguenti mostrano come aggiornare il valore TTL di un elemento.

------
#### [ Java ]

**SDK per Java 2.x**  
Aggiorna il TTL di un elemento DynamoDB esistente in una tabella.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

    public UpdateItemResponse updateItemWithTTL(
        final String tableName, final String primaryKeyValue, final String sortKeyValue) {
        // Get current time in epoch second format
        final long currentTime = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = currentTime + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        // Create the key map for the item to update
        final Map<String, AttributeValue> keyMap = new HashMap<>();
        keyMap.put(PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build());
        keyMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build());

        // Create the expression attribute values
        final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
        expressionAttributeValues.put(
            ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build());
        expressionAttributeValues.put(
            ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final UpdateItemRequest request = UpdateItemRequest.builder()
            .tableName(tableName)
            .key(keyMap)
            .updateExpression(UPDATE_EXPRESSION)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try {
            final UpdateItemResponse response = dynamoDbClient.updateItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return response;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
```
+  *Per i dettagli sulle API, consulta [UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem)la sezione API Reference.AWS SDK for Java 2.x * 

------
#### [ JavaScript ]

**SDK per JavaScript (v3)**  

```
import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const updateItem = async (tableName, partitionKey, sortKey, region = 'us-east-1') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);
    const expireAt = Math.floor((Date.now() + 90 * 24 * 60 * 60 * 1000) / 1000);

    const params = {
        TableName: tableName,
        Key: marshall({
            partitionKey: partitionKey,
            sortKey: sortKey
        }),
        UpdateExpression: "SET updatedAt = :c, expireAt = :e",
        ExpressionAttributeValues: marshall({
            ":c": currentTime,
            ":e": expireAt
        }),
    };

    try {
        const data = await client.send(new UpdateItemCommand(params));
        const responseData = unmarshall(data.Attributes);
        console.log("Item updated successfully: %s", responseData);
        return responseData;
    } catch (err) {
        console.error("Error updating item:", err);
        throw err;
    }
}

// Example usage (commented out for testing)
// updateItem('your-table-name', 'your-partition-key-value', 'your-sort-key-value');
```
+  Per i dettagli sull'API, consulta la sezione *AWS SDK per JavaScript API [UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand)Reference*. 

------
#### [ Python ]

**SDK per Python (Boto3)**  

```
from datetime import datetime, timedelta

import boto3


def update_dynamodb_item(table_name, region, primary_key, sort_key):
    """
    Update an existing DynamoDB item with a TTL.
    :param table_name: Name of the DynamoDB table
    :param region: AWS Region of the table - example `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :return: Void (nothing)
    """
    try:
        # Create the DynamoDB resource.
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Get the current time in epoch second format
        current_time = int(datetime.now().timestamp())

        # Calculate the expireAt time (90 days from now) in epoch second format
        expire_at = int((datetime.now() + timedelta(days=90)).timestamp())

        table.update_item(
            Key={"partitionKey": primary_key, "sortKey": sort_key},
            UpdateExpression="set updatedAt=:c, expireAt=:e",
            ExpressionAttributeValues={":c": current_time, ":e": expire_at},
        )

        print("Item updated successfully.")
    except Exception as e:
        print(f"Error updating item: {e}")


# Replace with your own values
update_dynamodb_item(
    "your-table-name", "us-west-2", "your-partition-key-value", "your-sort-key-value"
)
```
+  Per i dettagli sull'API, consulta [UpdateItem AWS](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem)*SDK for Python (Boto3) API Reference*. 

------

Gli esempi del TTL discussi in questa introduzione dimostrano un metodo per garantire che in una tabella vengano conservati solo gli elementi aggiornati di recente. Gli elementi aggiornati hanno una durata prolungata, mentre gli elementi non aggiornati dopo la creazione scadono e vengono eliminati gratuitamente, liberando spazio di archiviazione e mantenendo le tabelle pulite.

# Utilizzo di elementi scaduti e Time to Live
<a name="ttl-expired-items"></a>

Gli elementi scaduti in attesa di eliminazione possono essere filtrati dalle operazioni di lettura e scrittura. Ciò è utile negli scenari in cui i dati scaduti non sono più validi e non devono essere utilizzati. Se non vengono filtrati, continueranno a essere visualizzati nelle operazioni di lettura e scrittura finché non verranno eliminati dal processo in background.

**Nota**  
Questi elementi continuano a essere conteggiati ai fini dei costi di archiviazione e lettura fino a quando non vengono eliminati.

Le eliminazioni TTL possono essere identificate nei flussi DynamoDB, ma solo nella Regione in cui è avvenuta l’eliminazione. Le eliminazioni TTL che vengono replicate nelle aree della tabella globale non sono identificabili nei flussi DynamoDB nelle aree in cui viene replicata l’eliminazione.

## Filtraggio di elementi scaduti dalle operazioni di lettura
<a name="ttl-expired-items-filter"></a>

Per operazioni di lettura come [Scan](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html) e [Query](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html), un’espressione di filtro può filtrare gli elementi scaduti in attesa di eliminazione. Come illustrato nel seguente frammento di codice, l’espressione di filtro può filtrare gli elementi in cui il TTL è uguale o inferiore al momento corrente. Ad esempio, il codice dell’SDK per Python include un’istruzione di assegnazione che ottiene il momento corrente come variabile (`now`) e la converte in `int` per il formato ora epoch.

Gli esempi di codice seguenti mostrano come eseguire query su elementi TTL.

------
#### [ Java ]

**SDK per Java 2.x**  
Interroga l'espressione filtrata per raccogliere elementi TTL in una tabella DynamoDB utilizzando. AWS SDK for Java 2.x  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;

import java.util.Map;
import java.util.Optional;

        final QueryRequest request = QueryRequest.builder()
            .tableName(tableName)
            .keyConditionExpression(KEY_CONDITION_EXPRESSION)
            .filterExpression(FILTER_EXPRESSION)
            .expressionAttributeNames(expressionAttributeNames)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final QueryResponse response = ddb.query(request);
            System.out.println("Query successful. Found " + response.count() + " items that have not expired yet.");

            // Print each item
            response.items().forEach(item -> {
                System.out.println("Item: " + item);
            });

            return 0;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
```
+  Per informazioni dettagliate sull’API, consulta [Query](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/Query) nella *documentazione di riferimento dell’API AWS SDK for Java 2.x *. 

------
#### [ JavaScript ]

**SDK per (v3) JavaScript **  
Interroga l'espressione filtrata per raccogliere elementi TTL in una tabella DynamoDB utilizzando. AWS SDK per JavaScript  

```
import { DynamoDBClient, QueryCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const queryFiltered = async (tableName, primaryKey, region = 'us-east-1') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);

    const params = {
        TableName: tableName,
        KeyConditionExpression: "#pk = :pk",
        FilterExpression: "#ea > :ea",
        ExpressionAttributeNames: {
            "#pk": "primaryKey",
            "#ea": "expireAt"
        },
        ExpressionAttributeValues: marshall({
            ":pk": primaryKey,
            ":ea": currentTime
        })
    };

    try {
        const { Items } = await client.send(new QueryCommand(params));
        Items.forEach(item => {
            console.log(unmarshall(item))
        });
        return Items;
    } catch (err) {
        console.error(`Error querying items: ${err}`);
        throw err;
    }
}

// Example usage (commented out for testing)
// queryFiltered('your-table-name', 'your-partition-key-value');
```
+  Per informazioni dettagliate sull’API, consulta [Query](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/QueryCommand) nella *documentazione di riferimento dell’API AWS SDK per JavaScript *. 

------
#### [ Python ]

**SDK per Python (Boto3)**  
Interroga l'espressione filtrata per raccogliere elementi TTL in una tabella DynamoDB utilizzando. AWS SDK per Python (Boto3)  

```
from datetime import datetime

import boto3


def query_dynamodb_items(table_name, partition_key):
    """

    :param table_name: Name of the DynamoDB table
    :param partition_key:
    :return:
    """
    try:
        # Initialize a DynamoDB resource
        dynamodb = boto3.resource("dynamodb", region_name="us-east-1")

        # Specify your table
        table = dynamodb.Table(table_name)

        # Get the current time in epoch format
        current_time = int(datetime.now().timestamp())

        # Perform the query operation with a filter expression to exclude expired items
        # response = table.query(
        #    KeyConditionExpression=boto3.dynamodb.conditions.Key('partitionKey').eq(partition_key),
        #    FilterExpression=boto3.dynamodb.conditions.Attr('expireAt').gt(current_time)
        # )
        response = table.query(
            KeyConditionExpression=dynamodb.conditions.Key("partitionKey").eq(partition_key),
            FilterExpression=dynamodb.conditions.Attr("expireAt").gt(current_time),
        )

        # Print the items that are not expired
        for item in response["Items"]:
            print(item)

    except Exception as e:
        print(f"Error querying items: {e}")


# Call the function with your values
query_dynamodb_items("Music", "your-partition-key-value")
```
+  Per informazioni dettagliate sull’API, consulta [Query](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/Query) nella *documentazione di riferimento dell’API SDK for Python (Boto3)AWS *. 

------

## Scrittura in base a una condizione su elementi scaduti
<a name="ttl-expired-items-conditional-write"></a>

È possibile utilizzare un’espressione condizionale per evitare scritture su elementi scaduti. Il frammento di codice riportato di seguito è un aggiornamento condizionale che verifica se la scadenza è posteriore al momento corrente. Se true, l’operazione di scrittura continuerà.

Gli esempi di codice seguenti mostrano come aggiornare in modo condizionale il valore TTL di un elemento.

------
#### [ Java ]

**SDK per Java 2.x**  
Aggiorna il TTL di un elemento DynamoDB esistente in una tabella con una condizione.  

```
package com.amazon.samplelib.ttl;

import com.amazon.samplelib.CodeSampleUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse;

import java.util.Map;
import java.util.Optional;

/**
 * Updates an item in a DynamoDB table with TTL attributes using a conditional expression.
 * This class demonstrates how to conditionally update TTL expiration timestamps.
 */
public class UpdateTTLConditional {

    private static final String USAGE =
        """
            Usage:
                <tableName> <primaryKey> <sortKey> <region>
            Where:
                tableName - The Amazon DynamoDB table being queried.
                primaryKey - The name of the primary key. Also known as the hash or partition key.
                sortKey - The name of the sort key. Also known as the range attribute.
                region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1)
            """;
    private static final int DAYS_TO_EXPIRE = 90;
    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
    private static final String PRIMARY_KEY_ATTR = "primaryKey";
    private static final String SORT_KEY_ATTR = "sortKey";
    private static final String UPDATED_AT_ATTR = "updatedAt";
    private static final String EXPIRE_AT_ATTR = "expireAt";
    private static final String UPDATE_EXPRESSION = "SET " + UPDATED_AT_ATTR + "=:c, " + EXPIRE_AT_ATTR + "=:e";
    private static final String CONDITION_EXPRESSION = "attribute_exists(" + PRIMARY_KEY_ATTR + ")";
    private static final String SUCCESS_MESSAGE = "%s UpdateItem operation with TTL successful.";
    private static final String CONDITION_FAILED_MESSAGE = "Condition check failed. Item does not exist.";
    private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found.";

    private final DynamoDbClient dynamoDbClient;

    /**
     * Constructs an UpdateTTLConditional with a default DynamoDB client.
     */
    public UpdateTTLConditional() {
        this.dynamoDbClient = null;
    }

    /**
     * Constructs an UpdateTTLConditional with the specified DynamoDB client.
     *
     * @param dynamoDbClient The DynamoDB client to use
     */
    public UpdateTTLConditional(final DynamoDbClient dynamoDbClient) {
        this.dynamoDbClient = dynamoDbClient;
    }

    /**
     * Main method to demonstrate conditionally updating an item with TTL.
     *
     * @param args Command line arguments
     */
    public static void main(final String[] args) {
        try {
            int result = new UpdateTTLConditional().processArgs(args);
            System.exit(result);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

    /**
     * Process command line arguments and conditionally update an item with TTL.
     *
     * @param args Command line arguments
     * @return 0 if successful, non-zero otherwise
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     * @throws IllegalArgumentException If arguments are invalid
     */
    public int processArgs(final String[] args) {
        // Argument validation (remove or replace this line when reusing this code)
        CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE);

        final String tableName = args[0];
        final String primaryKey = args[1];
        final String sortKey = args[2];
        final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null)
            .map(Region::of)
            .orElse(Region.US_EAST_1);

        // Get current time in epoch second format
        final long currentTime = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = currentTime + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        // Create the key map for the item to update
        final Map<String, AttributeValue> keyMap = Map.of(
            PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKey).build(),
            SORT_KEY_ATTR, AttributeValue.builder().s(sortKey).build());

        // Create the expression attribute values
        final Map<String, AttributeValue> expressionAttributeValues = Map.of(
            ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build(),
            ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final UpdateItemRequest request = UpdateItemRequest.builder()
            .tableName(tableName)
            .key(keyMap)
            .updateExpression(UPDATE_EXPRESSION)
            .conditionExpression(CONDITION_EXPRESSION)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final UpdateItemResponse response = ddb.updateItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return 0;
        } catch (ConditionalCheckFailedException e) {
            System.err.println(CONDITION_FAILED_MESSAGE);
            throw e;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
}
```
+  *Per i dettagli sulle API, consulta [UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem)la sezione API Reference.AWS SDK for Java 2.x * 

------
#### [ JavaScript ]

**SDK per JavaScript (v3)**  
Aggiorna il TTL di un elemento DynamoDB esistente in una tabella con una condizione.  

```
import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const updateItemConditional = async (tableName, partitionKey, sortKey, region = 'us-east-1', newAttribute = 'default-value') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);

    const params = {
        TableName: tableName,
        Key: marshall({
            artist: partitionKey,
            album: sortKey
        }),
        UpdateExpression: "SET newAttribute = :newAttribute",
        ConditionExpression: "expireAt > :expiration",
        ExpressionAttributeValues: marshall({
            ':newAttribute': newAttribute,
            ':expiration': currentTime
        }),
        ReturnValues: "ALL_NEW"
    };

    try {
        const response = await client.send(new UpdateItemCommand(params));
        const responseData = unmarshall(response.Attributes);
        console.log("Item updated successfully: ", responseData);
        return responseData;
    } catch (error) {
        if (error.name === "ConditionalCheckFailedException") {
            console.log("Condition check failed: Item's 'expireAt' is expired.");
        } else {
            console.error("Error updating item: ", error);
        }
        throw error;
    }
};

// Example usage (commented out for testing)
// updateItemConditional('your-table-name', 'your-partition-key-value', 'your-sort-key-value');
```
+  Per i dettagli sull'API, consulta la sezione *AWS SDK per JavaScript API [UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand)Reference*. 

------
#### [ Python ]

**SDK per Python (Boto3)**  
Aggiorna il TTL di un elemento DynamoDB esistente in una tabella con una condizione.  

```
from datetime import datetime, timedelta

import boto3
from botocore.exceptions import ClientError


def update_dynamodb_item_ttl(table_name, region, primary_key, sort_key, ttl_attribute):
    """
    Updates an existing record in a DynamoDB table with a new or updated TTL attribute.

    :param table_name: Name of the DynamoDB table
    :param region: AWS Region of the table - example `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :param ttl_attribute: name of the TTL attribute in the target DynamoDB table
    :return:
    """
    try:
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Generate updated TTL in epoch second format
        updated_expiration_time = int((datetime.now() + timedelta(days=90)).timestamp())

        # Define the update expression for adding/updating a new attribute
        update_expression = "SET newAttribute = :val1"

        # Define the condition expression for checking if 'expireAt' is not expired
        condition_expression = "expireAt > :val2"

        # Define the expression attribute values
        expression_attribute_values = {":val1": ttl_attribute, ":val2": updated_expiration_time}

        response = table.update_item(
            Key={"primaryKey": primary_key, "sortKey": sort_key},
            UpdateExpression=update_expression,
            ConditionExpression=condition_expression,
            ExpressionAttributeValues=expression_attribute_values,
        )

        print("Item updated successfully.")
        return response["ResponseMetadata"]["HTTPStatusCode"]  # Ideally a 200 OK
    except ClientError as e:
        if e.response["Error"]["Code"] == "ConditionalCheckFailedException":
            print("Condition check failed: Item's 'expireAt' is expired.")
        else:
            print(f"Error updating item: {e}")
    except Exception as e:
        print(f"Error updating item: {e}")


# replace with your values
update_dynamodb_item_ttl(
    "your-table-name",
    "us-east-1",
    "your-partition-key-value",
    "your-sort-key-value",
    "your-ttl-attribute-value",
)
```
+  Per i dettagli sull'API, consulta [UpdateItem AWS](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem)*SDK for Python (Boto3) API Reference*. 

------

## Identificazione degli elementi eliminati nei flussi DynamoDB
<a name="ttl-expired-items-identifying"></a>

Il record Streams contiene un campo di identità utente `Records[<index>].userIdentity`. Gli elementi eliminati dal processo TTL hanno i seguenti campi:

```
Records[<index>].userIdentity.type
"Service"

Records[<index>].userIdentity.principalId
"dynamodb.amazonaws.com"
```

Il JSON seguente mostra la porzione rilevante di un singolo record di flussi:

```
"Records": [ 
  { 
	... 
		"userIdentity": {
		"type": "Service", 
      	"principalId": "dynamodb.amazonaws.com" 
   	} 
   ... 
	} 
]
```

# Esecuzione di query in DynamoDB
<a name="Query"></a>

Puoi usare l'operazione API `Query` in Amazon DynamoDB per trovare gli elementi in base ai valori delle chiavi primarie.

È necessario fornire il nome dell'attributo della chiave di partizione e un singolo valore per tale attributo. `Query` restituisce tutti gli elementi con lo stesso valore della chiave di partizione. Facoltativamente, puoi fornire un attributo della chiave di ordinamento e utilizzare un operatore di confronto per perfezionare i risultati della ricerca.

Per ulteriori informazioni su come usare `Query`, come la sintassi della richiesta, i parametri di risposta e altri esempi, vedere [Query](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html) nella *Documentazione di riferimento dell'API Amazon DynamoDB*.

**Topics**
+ [

# Espressioni di condizione della chiave per l’operazione Query in DynamoDB
](Query.KeyConditionExpressions.md)
+ [

# Espressioni di filtro per l’operazione Query in DynamoDB
](Query.FilterExpression.md)
+ [

# Impaginazione dei risultati delle query sulle tabelle in DynamoDB
](Query.Pagination.md)
+ [

# Altri aspetti dell’utilizzo dell’operazione Query in DynamoDB
](Query.Other.md)

# Espressioni di condizione della chiave per l’operazione Query in DynamoDB
<a name="Query.KeyConditionExpressions"></a>

Puoi utilizzare qualsiasi nome di attributo in un'espressione condizionale della chiave, a condizione che il primo carattere sia `a-z` o `A-Z` e che il resto dei caratteri (a iniziare dal secondo carattere, se presente) sia `a-z`, `A-Z` o `0-9`. Inoltre, il nome dell'attributo non deve essere una parola riservata di DynamoDB. Per l'elenco completo delle parole riservate, consulta [Parole riservate in DynamoDB](ReservedWords.md). Se un nome di attributo non soddisfa questi requisiti, devi definire un nome di attributo dell'espressione come un segnaposto. Per ulteriori informazioni, consulta [Nomi di attributi di espressione (alias) in DynamoDB](Expressions.ExpressionAttributeNames.md).

Per gli elementi con un determinato valore di chiave di partizione, DynamoDB li memorizza tutti insieme, ordinati in base al valore della chiave di ordinamento. In un'operazione `Query`, DynamoDB recupera gli elementi nell'ordine stabilito e quindi li elabora utilizzando `KeyConditionExpression` e qualsiasi `FilterExpression` eventualmente presente. Solo allora i risultati della `Query` vengono restituiti al client.

Un'operazione `Query` restituisce sempre un set di risultati. Se non vengono trovati item corrispondenti, il set di risultati è vuoto.

I risultati della `Query` sono sempre ordinati per il valore della chiave di ordinamento. Se il tipo di dati della chiave di ordinamento è `Number`, i risultati vengono restituiti in ordine numerico. In caso contrario, i risultati vengono restituiti nell'ordine di byte UTF-8. Per impostazione predefinita, l'ordinamento è crescente. Per invertire l'ordine, imposta il parametro `ScanIndexForward` su `false`.

Una singola operazione `Query` può recuperare un massimo di 1 MB di dati. Questo limite si applica prima che ai risultati venga applicato `FilterExpression` o `ProjectionExpression`. Se `LastEvaluatedKey` è presente nella risposta ed è non null, devi eseguire la paginazione del set di risultati (consulta [Impaginazione dei risultati delle query sulle tabelle in DynamoDB](Query.Pagination.md)).

## Esempi di espressioni di condizione della chiave
<a name="Query.KeyConditionExpressions-example"></a>

Per specificare i criteri di ricerca, è possibile utilizzare una *espressione di condizione chiave*, ovvero una stringa che determina gli elementi da leggere dalla tabella o dall'indice.

Devi specificare il nome e il valore della chiave di partizione come condizione di uguaglianza. Non puoi utilizzare un attributo non chiave in un'espressione di condizione chiave.

Facoltativamente puoi fornire una seconda condizione per la chiave di ordinamento (se presente). La condizione della chiave di ordinamento deve utilizzare uno dei seguenti operatori di confronto:
+ `a = b`— true se l'attributo *a* è uguale al valore *b*
+ `a < b`— vero se *a* è minore di *b*
+ `a <= b`— vero se *a* è minore o uguale a *b*
+ `a > b`— vero se *a* è maggiore di *b*
+ `a >= b`— vero se *a* è maggiore o uguale a *b*
+ `a BETWEEN b AND c`— vero se *a* è maggiore o uguale a *b* e minore o uguale a*c*.

È supportata anche la seguente funzione:
+ `begins_with (a, substr)`: true se il valore dell'attributo `a` inizia con una determinata sottostringa.

I seguenti esempi AWS Command Line Interface (AWS CLI) illustrano l'uso delle espressioni delle condizioni chiave. Queste espressioni usano segnaposti (come ad esempio `:name` e `:sub`) anziché i valori effettivi. Per ulteriori informazioni, consultare [Nomi di attributi di espressione (alias) in DynamoDB](Expressions.ExpressionAttributeNames.md) e [Utilizzo dei valori degli attributi di espressione in DynamoDB](Expressions.ExpressionAttributeValues.md).

**Example**  
Esegui la query sulla tabella `Thread` per un particolare `ForumName` (chiave di partizione). Tutti gli elementi con quel valore di `ForumName` vengono letti dalla query, perché la chiave di ordinamento (`Subject`) non è inclusa in `KeyConditionExpression`.  

```
aws dynamodb query \
    --table-name Thread \
    --key-condition-expression "ForumName = :name" \
    --expression-attribute-values  '{":name":{"S":"Amazon DynamoDB"}}'
```

**Example**  
Esegui la query sulla tabella `Thread` per un particolare `ForumName` (chiave di partizione); questa volta vengono restituiti solo gli elementi con uno specifico `Subject` (chiave di ordinamento).  

```
aws dynamodb query \
    --table-name Thread \
    --key-condition-expression "ForumName = :name and Subject = :sub" \
    --expression-attribute-values  file://values.json
```
Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `values.json`:  

```
{
    ":name":{"S":"Amazon DynamoDB"},
    ":sub":{"S":"DynamoDB Thread 1"}
}
```

**Example**  
Esegui la query sulla tabella `Reply` per un particolare `Id` (chiave di partizione); vengono restituiti solo gli elementi il cui `ReplyDateTime` (chiave di ordinamento) inizia con determinati caratteri.  

```
aws dynamodb query \
    --table-name Reply \
    --key-condition-expression "Id = :id and begins_with(ReplyDateTime, :dt)" \
    --expression-attribute-values  file://values.json
```
Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `values.json`:  

```
{
    ":id":{"S":"Amazon DynamoDB#DynamoDB Thread 1"},
    ":dt":{"S":"2015-09"}
}
```

# Espressioni di filtro per l’operazione Query in DynamoDB
<a name="Query.FilterExpression"></a>

Se devi perfezionare ulteriormente i risultati di `Query`, opzionalmente puoi fornire un'espressione filtro. Un'*espressione di filtro* determina quali item all'interno dei risultati di `Query` devono essere restituiti. Tutti gli altri risultati vengono scartati.

Un'espressione di filtro viene applicata al termine di un'operazione `Query`, ma prima che i risultati vengano restituiti. Pertanto, un'operazione `Query` consuma la stessa quantità di capacità in lettura, a prescindere dal fatto che sia presente un'espressione di filtro.

Un'operazione `Query` può recuperare un massimo di 1 MB di dati. Questo limite si applica prima che l'espressione di filtro venga valutata.

Un'espressione di filtro non può contenere attributi di chiave di partizione o chiave di ordinamento. Devi specificare quegli attributi nell'espressione della condizione di chiave e non nell'espressione di filtro.

La sintassi per un'espressione di filtro è simile a quella di un'espressione di condizione chiave. Le espressioni di filtro possono utilizzare gli stessi comparatori, funzioni e operatori logici come espressione di condizione chiave. Inoltre, le espressioni di filtro possono utilizzare l'operatore non uguale (`<>`), l’operatore `OR`, l’operatore `CONTAINS`, l’operatore `IN`, l’operatore `BEGINS_WITH`, l’operatore `BETWEEN`, l’operatore `EXISTS` e l’operatore `SIZE`. Per ulteriori informazioni, consultare [Espressioni di condizione della chiave per l’operazione Query in DynamoDB](Query.KeyConditionExpressions.md) e [Sintassi per le espressioni di filtro e condizioni](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.Syntax).

**Example**  
L' AWS CLI esempio seguente interroga la `Thread` tabella per un particolare `ForumName` (chiave di partizione) e `Subject` (chiave di ordinamento). Tra gli elementi trovati, vengono restituiti solo i thread di discussione più popolari, in altre parole solo i thread con più di un certo numero di `Views`.  

```
aws dynamodb query \
    --table-name Thread \
    --key-condition-expression "ForumName = :fn and Subject begins_with :sub" \
    --filter-expression "#v >= :num" \
    --expression-attribute-names '{"#v": "Views"}' \
    --expression-attribute-values file://values.json
```
Gli argomenti per `--expression-attribute-values` sono memorizzati nel file `values.json`:  

```
{
    ":fn":{"S":"Amazon DynamoDB"},
    ":sub":{"S":"DynamoDB Thread 1"},
    ":num":{"N":"3"}
}
```
Tenere presente che `Views` è una parola riservata in DynamoDB (vedere [Parole riservate in DynamoDB](ReservedWords.md)), quindi in questo esempio si usa `#v` come segnaposto. Per ulteriori informazioni, consulta [Nomi di attributi di espressione (alias) in DynamoDB](Expressions.ExpressionAttributeNames.md).

**Nota**  
Un'espressione filtro rimuove gli elementi dal set di risultati della `Query`. Se possibile, evita di utilizzare `Query` dove ti aspetti di recuperare un gran numero di item, ma sai che devi anche scartare la maggior parte di questi item.

# Impaginazione dei risultati delle query sulle tabelle in DynamoDB
<a name="Query.Pagination"></a>

DynamoDB esegue la *paginazione* dei risultati delle operazioni `Query`. Con la paginazione, i risultati della `Query` vengono divisi in "pagine" di dati la cui dimensione è al massimo 1 MB. Un'applicazione può elaborare la prima pagina dei risultati, quindi la seconda pagina e così via.

Una singola operazione `Query` restituisce solo un set di risultati che rientra nel limite di dimensione di 1 MB. Per determinare se ci sono più risultati e recuperarli una pagina alla volta, le applicazioni devono fare quanto segue: 

1. Esamina i risultati della `Query` di livello inferiore:
   + Se il risultato contiene un elemento `LastEvaluatedKey` che non è null, passa alla fase 2.
   + Se nel risultato *non* è presente un `LastEvaluatedKey`, allora non ci sono altri elementi da recuperare.

1. Costruzione di una `Query` con la stessa `KeyConditionExpression`. Tuttavia, questa volta, accettare il valore `LastEvaluatedKey` della fase 1 e usarlo come parametro `ExclusiveStartKey` nella nuova richiesta di `Query`.

1. Eseguire la nuova richiesta di `Query`.

1. Passa alla fase 1.

In altre parole, l'item `LastEvaluatedKey` della risposta di uno `Query` deve essere usato come item `ExclusiveStartKey` per la successiva richiesta di `Query`. Se non è presente un elemento `LastEvaluatedKey` nella risposta di uno `Query`, vuol dire che hai recuperato la pagina finale dei risultati. Se `LastEvaluatedKey` non è vuoto, non significa necessariamente che esistano più dati nel set di risultati. L'unico modo per sapere che hai raggiunto la fine del set di risultati è quando `LastEvaluatedKey` è vuoto.

È possibile utilizzare il AWS CLI per visualizzare questo comportamento. AWS CLI Invia ripetutamente `Query` richieste di basso livello a DynamoDB, `LastEvaluatedKey` finché non sono più presenti nei risultati. Considerate il seguente AWS CLI esempio che recupera i titoli dei film di un determinato anno.

```
aws dynamodb query --table-name Movies \
    --projection-expression "title" \
    --key-condition-expression "#y = :yyyy" \
    --expression-attribute-names '{"#y":"year"}' \
    --expression-attribute-values '{":yyyy":{"N":"1993"}}' \
    --page-size 5 \
    --debug
```

Normalmente, AWS CLI gestisce l'impaginazione automaticamente. Tuttavia, in questo esempio, il AWS CLI `--page-size` parametro limita il numero di elementi per pagina. Il parametro `--debug` consente di stampare le informazioni di livello inferiore relative alle richieste e alle risposte.

Se si esegue l'esempio, l'aspetto della prima risposta da DynamoDB sarà simile al seguente.

```
2017-07-07 11:13:15,603 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":5,"Items":[{"title":{"S":"A Bronx Tale"}},
{"title":{"S":"A Perfect World"}},{"title":{"S":"Addams Family Values"}},
{"title":{"S":"Alive"}},{"title":{"S":"Benny & Joon"}}],
"LastEvaluatedKey":{"year":{"N":"1993"},"title":{"S":"Benny & Joon"}},
"ScannedCount":5}'
```

L'item `LastEvaluatedKey` nella risposta indica che non tutti gli elementi sono stati recuperati. AWS CLI Quindi invia un'altra `Query` richiesta a DynamoDB. Questo modello di richiesta e risposta continua fino alla risposta finale.

```
2017-07-07 11:13:16,291 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":1,"Items":[{"title":{"S":"What\'s Eating Gilbert Grape"}}],"ScannedCount":1}'
```

L'assenza di `LastEvaluatedKey` indica che non ci sono più item da recuperare.

**Nota**  
 AWS SDKs Gestiscono le risposte DynamoDB di basso livello (inclusa la presenza o l'assenza di) e forniscono varie astrazioni per l'impaginazione `LastEvaluatedKey` dei risultati. `Query` Ad esempio, l'interfaccia del documento SDK per Java fornisce il supporto `java.util.Iterator` per poter esaminare i risultati uno alla volta.  
Per esempi di codice in vari linguaggi di programmazione, consulta la [Guida alle operazioni di base di Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/) e la documentazione dell'SDK AWS per il linguaggio in uso.

È inoltre possibile ridurre la dimensione della pagina limitando il numero di elementi nel set di risultati, con il parametro `Limit` dell’operazione `Query`.

Per ulteriori informazioni sull'esecuzione di query con DynamoDB, consulta [Esecuzione di query in DynamoDB](Query.md).

# Altri aspetti dell’utilizzo dell’operazione Query in DynamoDB
<a name="Query.Other"></a>

Questa sezione tratta aspetti aggiuntivi dell’operazione Query in DynamoDB, tra cui la limitazione delle dimensioni dei risultati, il conteggio degli elementi scansionati rispetto a quelli restituiti, il monitoraggio dell’utilizzo della capacità di lettura e il controllo della coerenza di lettura.

## Limitazione del numero di elementi nel set di risultati
<a name="Query.Limit"></a>

Con l'operazione `Query` puoi limitare il numero di elementi che vengono letti. A tale scopo, imposta il parametro `Limit` sul numero massimo di item desiderati.

Ad esempio, supponi di eseguire un'operazione `Query` su una tabella, con un valore `Limit` di `6` e senza un'espressione di filtro. Il risultato dell'operazione `Query` contiene i primi sei item della tabella che corrispondono all'espressione di condizione della chiave della richiesta.

Supponi ora di aggiungere un'espressione di filtro a `Query`. In questo caso, DynamoDB legge fino a sei elementi e restituisce solo quelli che corrispondono all'espressione di filtro. Il risultato `Query` finale contiene sei elementi o meno, anche se, se DynamoDB avesse continuato la lettura, più elementi avrebbero trovato la corrispondenza con l'espressione del filtro.

## Conteggio degli elementi nei risultati
<a name="Query.Count"></a>

Oltre agli elementi che corrispondono ai tuoi criteri, la risposta `Query` contiene i seguenti elementi:
+ `ScannedCount`: il numero di voci corrispondenti all'espressione di condizione della query *prima* dell'applicazione di un'espressione di filtro (se presente).
+ `Count`: il numero di elementi che rimangono *dopo* aver applicato un'espressione di filtro.

**Nota**  
Se non si utilizza un'espressione di filtro `ScannedCount` e `Count` hanno lo stesso valore.

Se la dimensione del set di risultati di `Query` è maggiore di 1 MB, `ScannedCount` e `Count` rappresentano solo un conteggio parziale degli elementi totali. Devi eseguire più operazioni `Query` per recuperare tutti i risultati (consulta [Impaginazione dei risultati delle query sulle tabelle in DynamoDB](Query.Pagination.md)).

Ogni risposta di `Query` contiene `ScannedCount` e `Count` per gli elementi che sono stati elaborati da quella particolare richiesta `Query`. Per ottenere i totali generali per tutte le richieste di `Query`, puoi mantenere in esecuzione il conteggio per entrambi gli elementi `ScannedCount` e `Count`.

## Unità di capacità utilizzate dalla query
<a name="Query.CapacityUnits"></a>

Puoi eseguire `Query` su qualsiasi tabella o indice secondario, purché tu fornisca il nome dell'attributo della chiave di partizione e un singolo valore per tale attributo. `Query` restituisce tutti gli elementi con tale valore di chiave di partizione. Facoltativamente, puoi fornire un attributo della chiave di ordinamento e utilizzare un operatore di confronto per perfezionare i risultati della ricerca. `Query` Le operazioni API consumano unità di capacità in lettura, come segue.


****  

| Se si esegue `Query` per un... | DynamoDB utilizza le unità di capacità in lettura da... | 
| --- | --- | 
| Tabella | La capacità di lettura assegnata della tabella. | 
| Indice secondario globale | La capacità di lettura assegnata dell'indice. | 
| Indice secondario locale | La capacità di lettura assegnata della tabella di base. | 

Per impostazione predefinita, un'operazione `Query` non restituisce alcun dato sulla capacità di lettura che consuma. Tuttavia, puoi specificare il parametro `ReturnConsumedCapacity` in una richiesta di `Query` per ottenere queste informazioni. Le seguenti sono le impostazioni valide per `ReturnConsumedCapacity`:
+ `NONE`: non vengono restituiti dati relativi alla capacità utilizzata. Questa è l'impostazione predefinita.
+ `TOTAL`: la risposta include il numero aggregato di unità di capacità di lettura utilizzate.
+ `INDEXES`: la risposta mostra il numero aggregato di unità di capacità di lettura utilizzate, insieme alla capacità utilizzata per ogni tabella e indice a cui è stato effettuato l'accesso.

DynamoDB calcola il numero di unità di capacità di lettura utilizzate in base al numero di elementi e alla dimensione di quegli elementi, non alla quantità di dati restituiti a un’applicazione. Per questo motivo, il numero di unità di capacità consumate è lo stesso sia che tu richieda tutti gli attributi (il comportamento predefinito) o solo alcuni di essi (usando un'espressione di proiezione). Il numero è lo stesso anche indipendentemente dal fatto che si utilizzi o meno un’espressione di filtro. `Query` utilizza un’unità di capacità di lettura minima per eseguire un’operazione a elevata consistenza di lettura al secondo o due letture a coerenza finale al secondo per un elemento di un massimo di 4 KB. Se è necessario leggere un elemento che è più grande di 4 KB, DynamoDB necessità di unità di richiesta di lettura aggiuntive. Le tabelle vuote e le tabelle molto grandi che hanno una quantità limitata di chiavi di partizione potrebbero comportare costi aggiuntivi RCUs oltre alla quantità di dati richiesti. Ciò copre il costo di evasione della richiesta `Query` anche in assenza di dati.

## Consistenza di lettura per la query
<a name="Query.ReadConsistency"></a>

Un'operazione `Query` esegue letture consistenti finali per impostazione predefinita. Ciò significa che i risultati di `Query` potrebbero non riflettere le modifiche dovute alle operazioni `PutItem` o `UpdateItem` completate di recente. Per ulteriori informazioni, consulta [Coerenza di lettura di DynamoDB](HowItWorks.ReadConsistency.md).

Se hai bisogno di elevata coerenza di lettura, imposta il parametro `ConsistentRead` su `true` nella richiesta di `Query`.

# Scansione di tabelle in DynamoDB
<a name="Scan"></a>

Un'operazione `Scan` in Amazon DynamoDB legge ogni elemento in una tabella o in un indice secondario. Per impostazione predefinita, un'operazione `Scan` restituisce tutti gli attributi dei dati per ogni item nella tabella o nell'indice. Puoi usare il parametro `ProjectionExpression` in modo che `Scan` restituisca solo alcuni attributi, piuttosto che tutti.

`Scan` restituisce sempre un set di risultati. Se non vengono trovati item corrispondenti, il set di risultati è vuoto.

Una singola richiesta `Scan` può recuperare un massimo di 1 MB di dati. Facoltativamente, DynamoDB può applicare un'espressione di filtro a questi dati, limitando i risultati prima che vengano restituiti all'utente.

**Topics**
+ [

## Espressioni di filtro per la scansione
](#Scan.FilterExpression)
+ [

## Limitazione del numero di elementi nel set di risultati
](#Scan.Limit)
+ [

## Paginazione dei risultati
](#Scan.Pagination)
+ [

## Conteggio degli elementi nei risultati
](#Scan.Count)
+ [

## Unità di capacità utilizzate dalla scansione
](#Scan.CapacityUnits)
+ [

## Consistenza di lettura per la scansione
](#Scan.ReadConsistency)
+ [

## Scansione parallela
](#Scan.ParallelScan)

## Espressioni di filtro per la scansione
<a name="Scan.FilterExpression"></a>

Se devi perfezionare ulteriormente i risultati di `Scan`, opzionalmente puoi fornire un'espressione filtro. Un'*espressione di filtro* determina quali item all'interno dei risultati di `Scan` devono essere restituiti. Tutti gli altri risultati vengono scartati.

Un'espressione di filtro viene applicata al termine di un'operazione `Scan`, ma prima che i risultati vengano restituiti. Pertanto, un'operazione `Scan` consuma la stessa quantità di capacità in lettura, a prescindere dal fatto che sia presente un'espressione di filtro.

Un'operazione `Scan` può recuperare un massimo di 1 MB di dati. Questo limite si applica prima che l'espressione di filtro venga valutata.

Con `Scan`, è possibile specificare qualsiasi attributo in un'espressione filtro, inclusi gli attributi di chiave di partizione e chiave di ordinamento.

La sintassi per un'espressione di filtro è identica a quella di un'espressione di condizione. Le espressioni di filtro possono utilizzare gli stessi comparatori, funzioni e operatori logici come espressione di condizione. Per ulteriori informazioni sugli operatori logici, consulta [Espressioni, operatori e funzioni di condizione e di filtro in DynamoDB](Expressions.OperatorsAndFunctions.md).

**Example**  
L'esempio seguente AWS Command Line Interface (AWS CLI) analizza la `Thread` tabella e restituisce solo gli ultimi elementi inviati da un determinato utente.  

```
aws dynamodb scan \
     --table-name Thread \
     --filter-expression "LastPostedBy = :name" \
     --expression-attribute-values '{":name":{"S":"User A"}}'
```

## Limitazione del numero di elementi nel set di risultati
<a name="Scan.Limit"></a>

L'operazione `Scan` consente di limitare il numero di item restituiti nel risultato. A questo scopo, imposta il parametro `Limit` sul numero massimo di item che devono essere restituiti dall'operazione `Scan`, prima di filtrare la valutazione dell'espressione.

Ad esempio, supponi di eseguire un'operazione `Scan` su una tabella con un valore `Limit` di `6` e senza un'espressione di filtro. Il risultato `Scan` contiene i primi sei elementi della tabella.

Supponi ora di aggiungere un'espressione di filtro a `Scan`. In questo caso, DynamoDB applica l'espressione di filtro ai sei elementi che sono stati restituiti, eliminando quelli che non corrispondono. Il risultato finale dell'operazione `Scan` contiene al massimo 6 item, a seconda del numero di quelli che sono stati filtrati.

## Paginazione dei risultati
<a name="Scan.Pagination"></a>

DynamoDB esegue la *paginazione* dei risultati delle operazioni `Scan`. Con la paginazione, i risultati della `Scan` vengono divisi in "pagine" di dati la cui dimensione è al massimo 1 MB. Un'applicazione può elaborare la prima pagina dei risultati, quindi la seconda pagina e così via.

Una singola operazione `Scan` restituisce solo un set di risultati che rientra nel limite di dimensione di 1 MB. 

Per determinare se ci sono più risultati e recuperarli una pagina alla volta, le applicazioni devono fare quanto segue:

1. Esamina i risultati della `Scan` di livello inferiore:
   + Se il risultato contiene un elemento `LastEvaluatedKey`, passa alla fase 2.
   + Se *non* è presente un item `LastEvaluatedKey` nel risultato non ci sono altri item da recuperare.

1. Costruire una nuova richiesta `Scan`, con gli stessi parametri della precedente. Tuttavia, questa volta, accettare il valore `LastEvaluatedKey` della fase 1 e usarlo come parametro `ExclusiveStartKey` nella nuova richiesta di `Scan`.

1. Eseguire la nuova richiesta di `Scan`.

1. Passa alla fase 1.

In altre parole, l'item `LastEvaluatedKey` della risposta di uno `Scan` deve essere usato come item `ExclusiveStartKey` per la successiva richiesta di `Scan`. Se non è presente un elemento `LastEvaluatedKey` nella risposta `Scan`, è stata recuperata la pagina finale dei risultati. L'assenza di `LastEvaluatedKey` è l'unico modo per sapere che hai raggiunto la fine del set di risultati.

È possibile utilizzare il AWS CLI per visualizzare questo comportamento. AWS CLI Invia `Scan` richieste di basso livello a DynamoDB, ripetutamente, `LastEvaluatedKey` fino a quando non è più presente nei risultati. Considerate l' AWS CLI esempio seguente che analizza l'intera `Movies` tabella ma restituisce solo i film di un genere particolare.

```
aws dynamodb scan \
    --table-name Movies \
    --projection-expression "title" \
    --filter-expression 'contains(info.genres,:gen)' \
    --expression-attribute-values '{":gen":{"S":"Sci-Fi"}}' \
    --page-size 100  \
    --debug
```

Normalmente, AWS CLI gestisce l'impaginazione automaticamente. Tuttavia, in questo esempio, il AWS CLI `--page-size` parametro limita il numero di elementi per pagina. Il parametro `--debug` consente di stampare le informazioni di livello inferiore relative alle richieste e alle risposte.

**Nota**  
I risultati dell'impaginazione varieranno anche in base ai parametri di input che vengono passati.   
L’utilizzo di `aws dynamodb scan --table-name Prices --max-items 1` restituisce un `NextToken`
L’utilizzo di `aws dynamodb scan --table-name Prices --limit 1` restituisce un `LastEvaluatedKey`.
Inoltre, tieni presente che l'uso di `--starting-token` in particolare richiede il valore `NextToken`. 

Se si esegue l'esempio, l'aspetto della prima risposta da DynamoDB sarà simile al seguente.

```
2017-07-07 12:19:14,389 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":7,"Items":[{"title":{"S":"Monster on the Campus"}},{"title":{"S":"+1"}},
{"title":{"S":"100 Degrees Below Zero"}},{"title":{"S":"About Time"}},{"title":{"S":"After Earth"}},
{"title":{"S":"Age of Dinosaurs"}},{"title":{"S":"Cloudy with a Chance of Meatballs 2"}}],
"LastEvaluatedKey":{"year":{"N":"2013"},"title":{"S":"Curse of Chucky"}},"ScannedCount":100}'
```

L'item `LastEvaluatedKey` nella risposta indica che non tutti gli elementi sono stati recuperati. AWS CLI Quindi invia un'altra `Scan` richiesta a DynamoDB. Questo modello di richiesta e risposta continua fino alla risposta finale.

```
2017-07-07 12:19:17,830 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":1,"Items":[{"title":{"S":"WarGames"}}],"ScannedCount":6}'
```

L'assenza di `LastEvaluatedKey` indica che non ci sono più item da recuperare.

**Nota**  
 AWS SDKs Gestiscono le risposte DynamoDB di basso livello (inclusa la presenza o l'assenza di) e forniscono varie astrazioni per l'impaginazione `LastEvaluatedKey` dei risultati. `Scan` Ad esempio, l'interfaccia del documento SDK per Java fornisce il supporto `java.util.Iterator` per poter esaminare i risultati uno alla volta.  
Per esempi di codice in vari linguaggi di programmazione, consulta la [Guida alle operazioni di base di Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/) e la documentazione dell'SDK AWS per il linguaggio in uso.

## Conteggio degli elementi nei risultati
<a name="Scan.Count"></a>

Oltre agli elementi che corrispondono ai tuoi criteri, la risposta `Scan` contiene i seguenti elementi:
+ `ScannedCount`: il numero di elementi valutati, prima di qualsiasi `ScanFilter`applicato. Un valore `ScannedCount` elevato con pochi o nessun risultato `Count` indica un'operazione `Scan` inefficiente. Se non hai utilizzato un filtro nella richiesta, allora `ScannedCount` e `Count` avranno lo stesso valore. 
+ `Count`: il numero di elementi che rimangono *dopo* aver applicato un'espressione di filtro (se presente).

**Nota**  
Se non si utilizza un'espressione di filtro, `ScannedCount` e `Count` hanno lo stesso valore.

Se la dimensione del set di risultati di `Scan` è maggiore di 1 MB, `ScannedCount` e `Count` rappresentano solo un conteggio parziale degli elementi totali. Devi eseguire più operazioni `Scan` per recuperare tutti i risultati (consulta [Paginazione dei risultati](#Scan.Pagination)).

Ogni risposta di `Scan` contiene `ScannedCount` e `Count` per gli elementi che sono stati elaborati da quella particolare richiesta `Scan`. Per ottenere i totali generali per tutte le richieste `Scan`, puoi mantenere in esecuzione il conteggio per entrambi gli elementi `ScannedCount` e `Count`.

## Unità di capacità utilizzate dalla scansione
<a name="Scan.CapacityUnits"></a>

È possibile effettuare la `Scan` di qualsiasi tabella o indice secondario. Le operazioni `Scan` consumano le unità di capacità di lettura come riportato di seguito:


****  

| Se si esegue `Scan` per un... | DynamoDB utilizza le unità di capacità in lettura da... | 
| --- | --- | 
| Tabella | La capacità di lettura assegnata della tabella. | 
| Indice secondario globale | La capacità di lettura assegnata dell'indice. | 
| Indice secondario locale | La capacità di lettura assegnata della tabella di base. | 

**Nota**  
L’accesso multi-account per le operazioni di scansione degli indici secondari non è attualmente supportato dalle [policy basate su risorse](access-control-resource-based.md).

Per impostazione predefinita, un'operazione `Scan` non restituisce alcun dato sulla capacità di lettura che consuma. Tuttavia, puoi specificare il parametro `ReturnConsumedCapacity` in una richiesta di `Scan` per ottenere queste informazioni. Le seguenti sono le impostazioni valide per `ReturnConsumedCapacity`:
+ `NONE`: non vengono restituiti dati relativi alla capacità utilizzata. Questa è l'impostazione predefinita.
+ `TOTAL`: la risposta include il numero aggregato di unità di capacità di lettura utilizzate.
+ `INDEXES`: la risposta mostra il numero aggregato di unità di capacità di lettura utilizzate, insieme alla capacità utilizzata per ogni tabella e indice a cui è stato effettuato l'accesso.

DynamoDB calcola il numero di unità di capacità di lettura utilizzate in base al numero di elementi e alla dimensione di quegli elementi, non alla quantità di dati restituiti a un’applicazione. Per questo motivo, il numero di unità di capacità consumate è lo stesso sia che tu richieda tutti gli attributi (il comportamento predefinito) o solo alcuni di essi (usando un'espressione di proiezione). Il numero è lo stesso anche indipendentemente dal fatto che si utilizzi o meno un’espressione di filtro. `Scan` utilizza un’unità di capacità di lettura minima per eseguire un’operazione a elevata consistenza di lettura al secondo o due letture a coerenza finale al secondo per un elemento di un massimo di 4 KB. Se è necessario leggere un elemento che è più grande di 4 KB, DynamoDB necessità di unità di richiesta di lettura aggiuntive. Le tabelle vuote e le tabelle molto grandi che hanno una quantità limitata di chiavi di partizione potrebbero comportare costi aggiuntivi RCUs oltre alla quantità di dati scansionati. Ciò copre il costo di evasione della richiesta `Scan` anche in assenza di dati.

## Consistenza di lettura per la scansione
<a name="Scan.ReadConsistency"></a>

Un'operazione `Scan` esegue letture consistenti finali per impostazione predefinita. Ciò significa che i risultati di `Scan` potrebbero non riflettere le modifiche dovute alle operazioni `PutItem` o `UpdateItem` completate di recente. Per ulteriori informazioni, consulta [Coerenza di lettura di DynamoDB](HowItWorks.ReadConsistency.md).

Se hai bisogno di letture fortemente consistenti, dal momento in cui inizia lo `Scan`, imposta il parametro `ConsistentRead` su `true` nella richiesta di `Scan`. Ciò garantisce che tutte le operazioni di scrittura completate prima dell'inizio dell'operazione `Scan` sono incluse nella risposta `Scan`. 

L'impostazione di `ConsistentRead` su `true` può essere utile negli scenari di backup o replica delle tabelle, insieme a [DynamoDB Streams](./Streams.html). Per prima cosa, usa `Scan` con `ConsistentRead` impostato su true, per ottenere una copia coerente dei dati nella tabella. Durante l'operazione `Scan`, DynamoDB Streams registra qualsiasi attività di scrittura aggiuntiva che si verifica sulla tabella. Al termine dell'operazione `Scan`, puoi applicare l'attività di scrittura dal flusso alla tabella.

**Nota**  
Un'operazione `Scan` con `ConsistentRead` impostato su `true` consuma il doppio delle unità di capacità in lettura, rispetto a lasciare `ConsistentRead` sul valore predefinito (`false`).

## Scansione parallela
<a name="Scan.ParallelScan"></a>

Per impostazione predefinita, l'operazione `Scan` elabora i dati in sequenza. Amazon DynamoDB restituisce i dati all'applicazione in incrementi di 1 MB e un'applicazione esegue ulteriori operazioni `Scan` per recuperare il successivo 1 MB di dati. 

Più grande è la tabella o l'indice da sottoporre a scansione, più tempo richiederà `Scan` per il completamento. Inoltre, un'operazione `Scan` sequenziale potrebbe non essere sempre in grado di utilizzare completamente la capacità effettiva di trasmissione di lettura assegnata: anche se DynamoDB distribuisce i dati di una tabella di grandi dimensioni su più partizioni fisiche, un'operazione `Scan` può leggere solo una partizione alla volta. Per questo motivo, la velocità effettiva di una `Scan` è vincolata dalla velocità effettiva massima di una singola partizione.

Per risolvere questi problemi, l'operazione `Scan` può dividere in modo logico una tabella o un indice secondario in più *segmenti*, con più worker dell'applicazione che eseguono la scansione dei segmenti in parallelo. Ogni worker può essere un thread (in linguaggi di programmazione che supportano il multithreading) o un processo del sistema operativo. Per eseguire una scansione parallela, ogni worker emette la propria richiesta `Scan` con i seguenti parametri:
+ `Segment`: un segmento che deve essere sottoposto a scansione da un particolare worker. Ogni worker deve utilizzare un valore diverso per `Segment`.
+ `TotalSegments`: il numero totale dei segmenti per la scansione parallela. Il valore deve essere identico al numero di worker che saranno utilizzati dall'applicazione.

Nel diagramma riportato di seguito viene illustrato come un'applicazione multithread esegue una `Scan` parallela con tre gradi di parallelismo.

![\[Un’applicazione multi-thread che esegue una scansione parallela dividendo una tabella in tre segmenti.\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/images/ParallelScan.png)




In questo diagramma, l'applicazione genera tre thread e assegna a ogni thread un numero. (Il primo numero dei segmenti è sempre 0.) Ogni thread emette una richiesta `Scan`, impostando `Segment` sul suo numero designato e `TotalSegments` su 3. Ogni thread esegue la scansione del segmento designato, recuperando i dati 1 MB alla volta e restituisce i dati al thread principale dell'applicazione.

DynamoDB *assegna gli elementi ai* segmenti applicando una funzione hash alla chiave di partizione di ciascun elemento. Per un determinato `TotalSegments` valore, tutti gli elementi con la stessa chiave di partizione vengono sempre assegnati allo stesso valore. `Segment` Ciò significa che in una tabella in cui *Item 1*, *Item 2* e *Item 3* condividono tutti `pk="account#123"` (ma hanno chiavi di ordinamento diverse), questi elementi verranno elaborati dallo stesso lavoratore, indipendentemente dai valori delle chiavi di ordinamento o dalla dimensione della *raccolta di elementi*.

Poiché l'assegnazione dei *segmenti* si basa esclusivamente sull'hash della chiave di partizione, i segmenti possono essere distribuiti in modo non uniforme. Alcuni segmenti potrebbero non contenere elementi, mentre altri potrebbero contenere molte chiavi di partizione con raccolte di elementi di grandi dimensioni. Di conseguenza, l'aumento del numero totale di segmenti non garantisce prestazioni di scansione più rapide, in particolare quando le chiavi di partizione non sono distribuite uniformemente nello spazio delle chiavi.

I valori per `Segment` e `TotalSegments` si applicano alle singole richieste `Scan` ed è possibile usare valori diversi in qualsiasi momento. Potrebbe essere necessario fare diverse prove con questi valori e il numero di worker utilizzati fino a quando l'applicazione non raggiunge le prestazioni migliori.

**Nota**  
Una scansione parallela con un numero elevato di worker può facilmente utilizzare tutta la velocità effettiva assegnata per la tabella o l'indice da sottoporre a scansione. È preferibile evitare tali scansioni se la tabella o l'indice subiscono anche un'intensa attività di lettura o scrittura da altre applicazioni.  
Per controllare la quantità di dati restituiti per ogni richiesta, utilizza il parametro `Limit`. Ciò consente di evitare situazioni in cui un worker utilizza tutta la velocità effettiva assegnata a spese di tutti gli altri worker.

# PartiQL: un linguaggio di query compatibile con SQL per Amazon DynamoDB
<a name="ql-reference"></a>

Amazon DynamoDB supporta [PartiQL](https://partiql.org/), un linguaggio di query compatibile con SQL, per selezionare, inserire, aggiornare ed eliminare i dati in Amazon DynamoDB. Utilizzando PartiQL, è possibile interagire facilmente con le tabelle DynamoDB ed eseguire query ad hoc utilizzando NoSQL Workbench e Console di gestione AWS DynamoDB for PartiQL. AWS Command Line Interface APIs 

Le operazioni PartiQL forniscono la stessa disponibilità, latenza e prestazioni delle altre operazioni del piano dati di DynamoDB.

Nelle sezioni seguenti viene descritta l'implementazione DynamoDB di PartiQL.

**Topics**
+ [

## Che cos'è PartiQL?
](#ql-reference.what-is)
+ [

## PartiQL in Amazon DynamoDB
](#ql-reference.what-is)
+ [Nozioni di base](ql-gettingstarted.md)
+ [Tipi di dati](ql-reference.data-types.md)
+ [Istruzioni](ql-reference.statements.md)
+ [Funzioni](ql-functions.md)
+ [Operatori](ql-operators.md)
+ [Transazioni](ql-reference.multiplestatements.transactions.md)
+ [Operazioni batch](ql-reference.multiplestatements.batching.md)
+ [Policy IAM](ql-iam.md)

## Che cos'è PartiQL?
<a name="ql-reference.what-is"></a>

*PartiQL* consente l'accesso alle query compatibile con SQL su più archivi dati contenenti dati strutturati, semistrutturati e nidificati. È ampiamente utilizzato in Amazon ed è ora disponibile come parte di molti AWS servizi, incluso DynamoDB.

Per la specifica PartiQL e un tutorial sul linguaggio delle query di base, consulta la [Documentazione di PartiQL](https://partiql.org/docs.html).

**Nota**  
Amazon DynamoDB supporta un *sottoinsieme* del linguaggio di query [PartiQL](https://partiql.org/).
Amazon DynamoDB non supporta il formato dati [Amazon Ion](http://amzn.github.io/ion-docs/) o i letterali Amazon Ion.

## PartiQL in Amazon DynamoDB
<a name="ql-reference.what-is"></a>

Per eseguire query PartiQL in DynamoDB, è possibile utilizzare:
+ La console DynamoDB
+ NoSQL Workbench
+ Il AWS Command Line Interface ()AWS CLI
+ Il DynamoDB APIs

Per informazioni sull'utilizzo di questi metodi per accedere a DynamoDB, consulta [Accesso a DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AccessingDynamoDB.html).

# Nozioni di base su PartiQL per DynamoDB
<a name="ql-gettingstarted"></a>

Questa sezione descrive come utilizzare PartiQL per DynamoDB dalla console Amazon DynamoDB, the () e DynamoDB. AWS Command Line Interface AWS CLI APIs

Nei seguenti esempi, la tabella DynamoDB definita nel tutorial [Nozioni di base su DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html) è un prerequisito.

[Per informazioni sull'utilizzo della console DynamoDB o DynamoDB per accedere a DynamoDB AWS Command Line Interface, vedere Accesso a APIs DynamoDB.](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AccessingDynamoDB.html)

Per [scaricare](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.settingup.html) e utilizzare [NoSQL Workbench](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.html) per creare istruzioni [PartiQL per DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html), seleziona **Operazioni PartiQL** nell'angolo in alto a destra dell'[Operation builder](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.querybuilder.operationbuilder.html) di NoSQL Workbench per DynamoDB.

------
#### [ Console ]

![\[Interfaccia dell’editor PartiQL che mostra il risultato dell’esecuzione dell’operazione Query sulla tabella Musica.\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/images/partiqlgettingstarted.png)


1. Accedi Console di gestione AWS e apri la console DynamoDB all'indirizzo. [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)

1. Nel pannello di navigazione sul lato sinistro della console seleziona **Editor PartiQL**.

1. Seleziona la tabella **Music**.

1. Scegli **Esegui query sulla tabella**. Questa azione genera una query che non determinerà una scansione completa della tabella.

1. Sostituisci `partitionKeyValue` con il valore stringa `Acme Band`. Sostituisci `sortKeyValue` con il valore stringa `Happy Day`.

1. Scegli il pulsante **Esegui**. 

1. È possibile visualizzare i risultati della query scegliendo i pulsanti **Vista tabella** o **Vista JSON**. 

------
#### [ NoSQL workbench ]

![\[Interfaccia NoSQL Workbench. Mostra un’istruzione PartiQL SELECT che è possibile eseguire sulla tabella Musica.\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/images/workbench/partiql.single.png)


1. Scegli **Istruzione PartiQL**.

1. Specifica la seguente [istruzione SELECT (SELEZIONA)](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.select.html) PartiQL. 

   ```
   SELECT *                                         
   FROM Music  
   WHERE Artist=? and SongTitle=?
   ```

1. Per specificare un valore per i parametri `Artist` e `SongTitle`:

   1. Scegli **Parametri di richiesta facoltativi**.

   1. Scegli **Aggiungi nuovi parametri**.

   1. Scegli il tipo di attributo **string** e il valore `Acme Band`.

   1. Ripeti i passaggi b e c, quindi scegli il tipo **string** e il valore `PartiQL Rocks`. 

1. Per generare codice, selezionare **Generate code (Genera codice)**.

   Selezionare la lingua desiderata dalle schede visualizzate. È possibile copiare questo codice e utilizzarlo nell'applicazione.

1. Per eseguire l'operazione immediatamente, seleziona **Esegui**.

------
#### [ AWS CLI ]

1. Crea un elemento nella tabella `Music` utilizzando l'istruzione INSERT (INSERISCI) PartiQL. 

   ```
   aws dynamodb execute-statement --statement "INSERT INTO Music  \
   					    VALUE  \
   					    {'Artist':'Acme Band','SongTitle':'PartiQL Rocks'}"
   ```

1. Recupera un elemento dalla tabella Music utilizzando l'istruzione SELECT (SELEZIONA) PartiQL.

   ```
   aws dynamodb execute-statement --statement "SELECT * FROM Music   \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

1. Aggiorna un elemento nella tabella `Music` utilizzando l'istruzione UPDATE (AGGIORNA) PartiQL.

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardsWon=1  \
                                               SET AwardDetail={'Grammys':[2020, 2018]}  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   Aggiungi un valore di elenco per un elemento nella tabella `Music`. 

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   Rimuovi un valore di elenco per un elemento nella tabella `Music`. 

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               REMOVE AwardDetail.Grammys[2]  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   Aggiungi un nuovo membro della mappa per un elemento nella tabella `Music`. 

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardDetail.BillBoard=[2020]  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   Aggiungi un nuovo attributo del set di stringhe per un elemento nella tabella `Music`. 

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET BandMembers =<<'member1', 'member2'>>  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   Aggiungi un attributo del set di stringhe per un elemento nella tabella `Music`. 

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET BandMembers =set_add(BandMembers, <<'newmember'>>)  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

1. Elimina un elemento dalla tabella `Music` utilizzando l'istruzione DELETE (ELIMINA) PartiQL.

   ```
   aws dynamodb execute-statement --statement "DELETE  FROM Music  \
       WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

------
#### [ Java ]

```
import java.util.ArrayList;
import java.util.List;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import software.amazon.dynamodb.AmazonDynamoDB;
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import software.amazon.dynamodb.model.AttributeValue;
import software.amazon.dynamodb.model.ConditionalCheckFailedException;
import software.amazon.dynamodb.model.ExecuteStatementRequest;
import software.amazon.dynamodb.model.ExecuteStatementResult;
import software.amazon.dynamodb.model.InternalServerErrorException;
import software.amazon.dynamodb.model.ItemCollectionSizeLimitExceededException;
import software.amazon.dynamodb.model.ProvisionedThroughputExceededException;
import software.amazon.dynamodb.model.RequestLimitExceededException;
import software.amazon.dynamodb.model.ResourceNotFoundException;
import software.amazon.dynamodb.model.TransactionConflictException;

public class DynamoDBPartiQGettingStarted {

    public static void main(String[] args) {
        // Create the DynamoDB Client with the region you want
        AmazonDynamoDB dynamoDB = createDynamoDbClient("us-west-1");

        try {
            // Create ExecuteStatementRequest
            ExecuteStatementRequest executeStatementRequest = new ExecuteStatementRequest();
            List<AttributeValue> parameters= getPartiQLParameters();

            //Create an item in the Music table using the INSERT PartiQL statement
            processResults(executeStatementRequest(dynamoDB, "INSERT INTO Music value {'Artist':?,'SongTitle':?}", parameters));

            //Retrieve an item from the Music table using the SELECT PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "SELECT * FROM Music  where Artist=? and SongTitle=?", parameters));

            //Update an item in the Music table using the UPDATE PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]}  where Artist=? and SongTitle=?", parameters));

            //Add a list value for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  where Artist=? and SongTitle=?", parameters));

            //Remove a list value for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music REMOVE AwardDetail.Grammys[2]   where Artist=? and SongTitle=?", parameters));

            //Add a new map member for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music set AwardDetail.BillBoard=[2020] where Artist=? and SongTitle=?", parameters));

            //Add a new string set attribute for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET BandMembers =<<'member1', 'member2'>> where Artist=? and SongTitle=?", parameters));

            //update a string set attribute for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET BandMembers =set_add(BandMembers, <<'newmember'>>) where Artist=? and SongTitle=?", parameters));

            //Retrieve an item from the Music table using the SELECT PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "SELECT * FROM Music  where Artist=? and SongTitle=?", parameters));

            //delete an item from the Music Table
            processResults(executeStatementRequest(dynamoDB, "DELETE  FROM Music  where Artist=? and SongTitle=?", parameters));
        } catch (Exception e) {
            handleExecuteStatementErrors(e);
        }
    }

    private static AmazonDynamoDB createDynamoDbClient(String region) {
        return AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
    }

    private static List<AttributeValue> getPartiQLParameters() {
        List<AttributeValue> parameters = new ArrayList<AttributeValue>();
        parameters.add(new AttributeValue("Acme Band"));
        parameters.add(new AttributeValue("PartiQL Rocks"));
        return parameters;
    }

    private static ExecuteStatementResult executeStatementRequest(AmazonDynamoDB client, String statement, List<AttributeValue> parameters ) {
        ExecuteStatementRequest request = new ExecuteStatementRequest();
        request.setStatement(statement);
        request.setParameters(parameters);
        return client.executeStatement(request);
    }

    private static void processResults(ExecuteStatementResult executeStatementResult) {
        System.out.println("ExecuteStatement successful: "+ executeStatementResult.toString());

    }

    // Handles errors during ExecuteStatement execution. Use recommendations in error messages below to add error handling specific to
    // your application use-case.
    private static void handleExecuteStatementErrors(Exception exception) {
        try {
            throw exception;
        } catch (ConditionalCheckFailedException ccfe) {
            System.out.println("Condition check specified in the operation failed, review and update the condition " +
                                       "check before retrying. Error: " + ccfe.getErrorMessage());
        } catch (TransactionConflictException tce) {
            System.out.println("Operation was rejected because there is an ongoing transaction for the item, generally " +
                                       "safe to retry with exponential back-off. Error: " + tce.getErrorMessage());
        } catch (ItemCollectionSizeLimitExceededException icslee) {
            System.out.println("An item collection is too large, you\'re using Local Secondary Index and exceeded " +
                                       "size limit of items per partition key. Consider using Global Secondary Index instead. Error: " + icslee.getErrorMessage());
        } catch (Exception e) {
            handleCommonErrors(e);
        }
    }

    private static void handleCommonErrors(Exception exception) {
        try {
            throw exception;
        } catch (InternalServerErrorException isee) {
            System.out.println("Internal Server Error, generally safe to retry with exponential back-off. Error: " + isee.getErrorMessage());
        } catch (RequestLimitExceededException rlee) {
            System.out.println("Throughput exceeds the current throughput limit for your account, increase account level throughput before " +
                                       "retrying. Error: " + rlee.getErrorMessage());
        } catch (ProvisionedThroughputExceededException ptee) {
            System.out.println("Request rate is too high. If you're using a custom retry strategy make sure to retry with exponential back-off. " +
                                       "Otherwise consider reducing frequency of requests or increasing provisioned capacity for your table or secondary index. Error: " +
                                       ptee.getErrorMessage());
        } catch (ResourceNotFoundException rnfe) {
            System.out.println("One of the tables was not found, verify table exists before retrying. Error: " + rnfe.getErrorMessage());
        } catch (AmazonServiceException ase) {
            System.out.println("An AmazonServiceException occurred, indicates that the request was correctly transmitted to the DynamoDB " +
                                       "service, but for some reason, the service was not able to process it, and returned an error response instead. Investigate and " +
                                       "configure retry strategy. Error type: " + ase.getErrorType() + ". Error message: " + ase.getErrorMessage());
        } catch (AmazonClientException ace) {
            System.out.println("An AmazonClientException occurred, indicates that the client was unable to get a response from DynamoDB " +
                                       "service, or the client was unable to parse the response from the service. Investigate and configure retry strategy. "+
                                       "Error: " + ace.getMessage());
        } catch (Exception e) {
            System.out.println("An exception occurred, investigate and configure retry strategy. Error: " + e.getMessage());
        }
    }

}
```

------

## Utilizzo di istruzioni parametrizzate
<a name="ql-gettingstarted.parameterized"></a>

Invece di incorporare i valori direttamente in una stringa di istruzioni PartiQL, è possibile utilizzare i segnaposto con punto interrogativo `?` () e fornire i valori separatamente nel campo. `Parameters` Ciascuno `?` viene sostituito dal valore del parametro corrispondente, nell'ordine in cui vengono forniti.

L'uso di istruzioni con parametri è una buona pratica perché separa la struttura delle istruzioni dai valori dei dati, semplificando la lettura e il riutilizzo delle istruzioni. Inoltre, evita la necessità di formattare manualmente ed eliminare i valori degli attributi nella stringa dell'istruzione.

Le istruzioni con parametri sono supportate nelle operazioni `ExecuteStatement` e`BatchExecuteStatement`. `ExecuteTransaction`

Gli esempi seguenti recuperano un elemento dalla `Music` tabella utilizzando valori parametrizzati per la chiave di partizione e la chiave di ordinamento.

------
#### [ AWS CLI parameterized ]

```
aws dynamodb execute-statement \
    --statement "SELECT * FROM \"Music\" WHERE Artist=? AND SongTitle=?" \
    --parameters '[{"S": "Acme Band"}, {"S": "PartiQL Rocks"}]'
```

------
#### [ Java parameterized ]

```
List<AttributeValue> parameters = new ArrayList<>();
parameters.add(new AttributeValue("Acme Band"));
parameters.add(new AttributeValue("PartiQL Rocks"));

ExecuteStatementRequest request = new ExecuteStatementRequest()
    .withStatement("SELECT * FROM Music WHERE Artist=? AND SongTitle=?")
    .withParameters(parameters);

ExecuteStatementResult result = dynamoDB.executeStatement(request);
```

------
#### [ Python parameterized ]

```
response = dynamodb_client.execute_statement(
    Statement="SELECT * FROM Music WHERE Artist=? AND SongTitle=?",
    Parameters=[
        {'S': 'Acme Band'},
        {'S': 'PartiQL Rocks'}
    ]
)
```

------

**Nota**  
L'esempio Java nella precedente sezione introduttiva utilizza dappertutto istruzioni con parametri. Il `getPartiQLParameters()` metodo crea l'elenco dei parametri e ogni istruzione utilizza `?` segnaposto anziché valori in linea.

# Tipi di dati PartiQL per DynamoDB
<a name="ql-reference.data-types"></a>

Nella tabella seguente sono elencati i tipi di dati che è possibile utilizzare con PartiQL per DynamoDB.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/ql-reference.data-types.html)

## Esempi
<a name="ql-reference.data-types"></a>

Nell'istruzione seguente viene illustrato come inserire i seguenti tipi di dati: `String`, `Number`, `Map`, `List`, `Number Set` e `String Set`.

```
INSERT INTO TypesTable value {'primarykey':'1', 
'NumberType':1,
'MapType' : {'entryname1': 'value', 'entryname2': 4}, 
'ListType': [1,'stringval'], 
'NumberSetType':<<1,34,32,4.5>>, 
'StringSetType':<<'stringval','stringval2'>>
}
```

La seguente istruzione illustra come inserire nuovi elementi nei tipi `Map`, `List`, `Number Set` e `String Set` e come modificare il valore di un tipo `Number`.

```
UPDATE TypesTable 
SET NumberType=NumberType + 100 
SET MapType.NewMapEntry=[2020, 'stringvalue', 2.4]
SET ListType = LIST_APPEND(ListType, [4, <<'string1', 'string2'>>])
SET NumberSetType= SET_ADD(NumberSetType, <<345, 48.4>>)
SET StringSetType = SET_ADD(StringSetType, <<'stringsetvalue1', 'stringsetvalue2'>>)
WHERE primarykey='1'
```

La seguente istruzione illustra come rimuovere gli elementi dai tipi `Map`, `List`, `Number Set` e `String Set` e come modificare il valore di un tipo `Number`.

```
UPDATE TypesTable 
SET NumberType=NumberType - 1
REMOVE ListType[1]
REMOVE MapType.NewMapEntry
SET NumberSetType = SET_DELETE( NumberSetType, <<345>>)
SET StringSetType = SET_DELETE( StringSetType, <<'stringsetvalue1'>>)
WHERE primarykey='1'
```

Per ulteriori informazioni, consulta [Tipi di dati di DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes).

# Istruzioni PartiQL per DynamoDB
<a name="ql-reference.statements"></a>

Amazon DynamoDB supporta le seguenti istruzioni PartiQL.

**Nota**  
DynamoDB non supporta tutte le istruzioni PartiQL.  
Questo riferimento fornisce esempi di sintassi di base ed esempi di utilizzo delle istruzioni PartiQL eseguite manualmente utilizzando AWS CLI o. APIs

Il *linguaggio di manipolazione dei dati* (DML, Data Manipulation Language) è l'insieme di istruzioni PartiQL utilizzate per gestire i dati nelle tabelle DynamoDB. Le istruzioni DML vengono utilizzate per aggiungere, modificare o eliminare i dati in una tabella.

Sono supportate le seguenti istruzioni DML e del linguaggio di query:
+ [Istruzioni SELECT PartiQL per DynamoDB](ql-reference.select.md)
+ [Istruzioni UPDATE PartiQL per DynamoDB](ql-reference.update.md)
+ [Istruzioni INSERT PartiQL per DynamoDB](ql-reference.insert.md)
+ [Istruzioni DELETE PartiQL per DynamoDB](ql-reference.delete.md)

Anche [Esecuzione di transazioni con PartiQL per DynamoDB](ql-reference.multiplestatements.transactions.md) e [Esecuzione di operazioni in batch con PartiQL per DynamoDB](ql-reference.multiplestatements.batching.md) sono supportati da PartiQL per DynamoDB.

# Istruzioni SELECT PartiQL per DynamoDB
<a name="ql-reference.select"></a>

Utilizza l'istruzione `SELECT` per recuperare i dati da una tabella in Amazon DynamoDB.

L’uso di un’istruzione `SELECT` può comportare una scansione completa della tabella se non si fornisce una condizione di uguaglianza o IN con una chiave di partizione nella clausola WHERE. L'operazione di scansione esamina ogni elemento per i valori richiesti e può utilizzare la velocità effettiva assegnata per una tabella o un indice di grandi dimensioni in un'unica operazione. 

Se desideri evitare la scansione completa della tabella in PartiQL, è possibile:
+ Crea le tue istruzioni `SELECT` per non provocare scansioni complete della tabella assicurandoti che la [condizione della clausola WHERE (DOVE)](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.select.html#ql-reference.select.parameters) sia configurata di conseguenza.
+ Disabilitare le scansioni di tabelle complete utilizzando la policy IAM specificata in [Esempio: Consentire le istruzioni Select e rifiutare le istruzioni di scansione completa della tabella in PartiQL per DynamoDB](ql-iam.md#access-policy-ql-iam-example6), nella Guida per gli sviluppatori di DynamoDB.

Per ulteriori informazioni, consulta la sezione [Best practice per eseguire query e scansioni di dati](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-query-scan.html) nella Guida per gli sviluppatori di DynamoDB.

**Topics**
+ [

## Sintassi
](#ql-reference.select.syntax)
+ [

## Parameters
](#ql-reference.select.parameters)
+ [

## Esempi
](#ql-reference.select.examples)

## Sintassi
<a name="ql-reference.select.syntax"></a>

```
SELECT expression  [, ...] 
FROM table[.index]
[ WHERE condition ] [ [ORDER BY key [DESC|ASC] , ...]
```

## Parameters
<a name="ql-reference.select.parameters"></a>

***expression***  
(Obbligatorio) Una proiezione formata dal carattere jolly `*` o un elenco di proiezione di uno o più nomi di attributi o percorsi di documento dal set di risultati. Un'espressione può essere costituita da chiamate a [Utilizzo delle funzioni PartiQL con DynamoDB](ql-functions.md) o da campi modificati da [Operatori PartiQL aritmetici, di confronto e logici per DynamoDB](ql-operators.md).

***table***  
(Obbligatorio) Il nome della tabella per cui eseguire la query.

***index***  
(Facoltativo) Il nome dell'indice su cui eseguire una query.  
È necessario aggiungere virgolette doppie al nome della tabella e al nome dell'indice quando si esegue una query su un indice.  

```
SELECT * 
FROM "TableName"."IndexName"
```

***condition***  
(Facoltativo) I criteri di selezione per la query.  
Per garantire che una istruzione `SELECT` non comporti una scansione completa della tabella, la condizione della clausola `WHERE` deve specificare una chiave di partizione. Utilizza l'operatore di uguaglianza o IN.  
Ad esempio, in presenza di una tabella `Orders` con una chiave di partizione `OrderID` e altri attributi non chiave, tra cui `Address`, le istruzioni seguenti non comportano una scansione completa della tabella:  

```
SELECT * 
FROM "Orders" 
WHERE OrderID = 100

SELECT * 
FROM "Orders" 
WHERE OrderID = 100 and Address='some address'

SELECT * 
FROM "Orders" 
WHERE OrderID = 100 or OrderID = 200

SELECT * 
FROM "Orders" 
WHERE OrderID IN [100, 300, 234]
```
Le seguenti istruzioni `SELECT`, tuttavia, provocheranno una scansione completa della tabella:  

```
SELECT * 
FROM "Orders" 
WHERE OrderID > 1

SELECT * 
FROM "Orders" 
WHERE Address='some address'

SELECT * 
FROM "Orders" 
WHERE OrderID = 100 OR Address='some address'
```

***key***  
(Facoltativo) Una chiave hash o una chiave di ordinamento da utilizzare per ordinare i risultati restituiti. L'ordine di default è crescente (`ASC`); specifica `DESC` se desideri che i risultati vengano rigenerati in ordine decrescente.

**Nota**  
Se si omette la clausola `WHERE`, saranno recuperati tutti gli elementi della tabella.

## Esempi
<a name="ql-reference.select.examples"></a>

La seguente query restituisce un elemento, se esistente, dalla tabella `Orders` specificando la chiave di partizione, `OrderID`, e utilizzando l'operatore di uguaglianza.

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID = 1
```

La seguente query restituisce tutti gli elementi nella tabella `Orders` che hanno una chiave di partizione specifica, `OrderID`, i valori che utilizzano l'operatore OR.

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID = 1 OR OrderID = 2
```

La seguente query restituisce tutti gli elementi nella tabella `Orders` che hanno una chiave di partizione specifica, `OrderID`, i valori che utilizzano l'operatore IN. I risultati restituiti sono in ordine decrescente, in base al valore dell'attributo della chiave `OrderID`.

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID IN [1, 2, 3] ORDER BY OrderID DESC
```

La seguente query mostra una scansione completa della tabella che restituisce tutti gli elementi dalla tabella `Orders` che hanno un `Total` maggiore di 500, dove `Total` è un attributo non chiave.

```
SELECT OrderID, Total 
FROM "Orders"
WHERE Total > 500
```

La seguente query mostra una scansione completa della tabella che restituisce tutti gli elementi dalla tabella `Orders` in un intervallo di ordinamento `Total` specifico, utilizzando l'operatore IN e un attributo non chiave `Total`.

```
SELECT OrderID, Total 
FROM "Orders"
WHERE Total IN [500, 600]
```

La seguente query mostra una scansione completa della tabella che restituisce tutti gli elementi dalla tabella `Orders` in un intervallo di ordinamento `Total` specifico, utilizzando l'operatore BETWEEN e un attributo non chiave `Total`.

```
SELECT OrderID, Total 
FROM "Orders" 
WHERE Total BETWEEN 500 AND 600
```

La seguente query restituisce la prima data in cui è stato utilizzato un dispositivo firestick specificando la chiave di partizione `CustomerID` e la chiave di ordinamento `MovieID` nella condizione clausola WHERE (DOVE) e utilizzando percorsi documento nella clausola SELECT (SELEZIONA).

```
SELECT Devices.FireStick.DateWatched[0] 
FROM WatchList 
WHERE CustomerID= 'C1' AND MovieID= 'M1'
```

La seguente query mostra una scansione completa della tabella che restituisce l'elenco degli elementi in cui un dispositivo firestick è stato utilizzato per la prima volta dopo il 12/12/19 utilizzando percorsi di documento nella condizione della clausola WHERE (DOVE).

```
SELECT Devices 
FROM WatchList 
WHERE Devices.FireStick.DateWatched[0] >= '12/24/19'
```

# Istruzioni UPDATE PartiQL per DynamoDB
<a name="ql-reference.update"></a>

Utilizza l'istruzione `UPDATE` per modificare il valore di uno o più attributi all'interno di un elemento in una tabella Amazon DynamoDB. 

**Nota**  
È possibile aggiornare solo un elemento alla volta; non è possibile emettere una singola istruzione PartiQL DynamoDB che aggiorna più elementi. Per informazioni sull'aggiornamento di più elementi, consulta [Esecuzione di transazioni con PartiQL per DynamoDB](ql-reference.multiplestatements.transactions.md) o [Esecuzione di operazioni in batch con PartiQL per DynamoDB](ql-reference.multiplestatements.batching.md).

**Topics**
+ [

## Sintassi
](#ql-reference.update.syntax)
+ [

## Parameters
](#ql-reference.update.parameters)
+ [

## Valore restituito
](#ql-reference.update.return)
+ [

## Esempi
](#ql-reference.update.examples)

## Sintassi
<a name="ql-reference.update.syntax"></a>

```
UPDATE  table  
[SET | REMOVE]  path  [=  data] […]
WHERE condition [RETURNING returnvalues]
<returnvalues>  ::= [ALL OLD | MODIFIED OLD | ALL NEW | MODIFIED NEW] *
```

## Parameters
<a name="ql-reference.update.parameters"></a>

***table***  
(Obbligatorio) La tabella contenente i dati da modificare.

***path***  
(Obbligatorio) Un nome attributo o un percorso di documento da creare o modificare.

***data***  
(Obbligatorio) Un valore di attributo o il risultato di un'operazione.  
Le operazioni supportate da utilizzare con SET sono:  
+ LIST\$1APPEND: aggiunge un valore a un tipo di elenco.
+ SET\$1ADD: aggiunge un valore a un numero o un set di stringhe.
+ SET\$1DELETE: rimuove un valore da un numero o un set di stringhe.

***condition***  
(Obbligatorio) I criteri di selezione per l'elemento da modificare. Questa condizione deve essere risolta in un singolo valore di chiave primaria.

***returnvalues***  
(Facoltativo) Utilizza `returnvalues` se desideri ottenere gli attributi dell'elemento come appaiono prima o dopo l'aggiornamento. I valori validi sono:   
+ `ALL OLD *`: restituisce tutti gli attributi dell'elemento come apparivano prima dell'operazione di aggiornamento.
+ `MODIFIED OLD *`: restituisce solo gli attributi aggiornati come apparivano prima dell'operazione di aggiornamento.
+ `ALL NEW *`: restituisce tutti gli attributi dell'elemento come appaiono dopo l'operazione di aggiornamento.
+ `MODIFIED NEW *`: restituisce solo gli attributi aggiornati come appaiono dopo l'operazione `UpdateItem`.

## Valore restituito
<a name="ql-reference.update.return"></a>

Questa istruzione non restituisce un valore a meno che non sia stato specificato il parametro `returnvalues`.

**Nota**  
Se la clausola WHERE (DOVE) dell'istruzione UPDATE (AGGIORNA) non restituisce true per alcun elemento nella tabella DynamoDB, viene restituito `ConditionalCheckFailedException`.

## Esempi
<a name="ql-reference.update.examples"></a>

Aggiorna un valore dell'attributo in un elemento esistente. Se l'attributo non esiste, ne verrà creato uno.

La seguente query aggiorna un elemento nella tabella `"Music"` aggiungendo un attributo di tipo number (`AwardsWon`) e un attributo di tipo map (`AwardDetail`).

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

È possibile aggiungere `RETURNING ALL OLD *` per riportare gli attributi così come apparivano prima dell'operazione `Update`.

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
RETURNING ALL OLD *
```

Restituisce quanto segue:

```
{
    "Items": [
        {
            "Artist": {
                "S": "Acme Band"
            },
            "SongTitle": {
                "S": "PartiQL Rocks"
            }
        }
    ]
}
```

È possibile aggiungere `RETURNING ALL NEW *` per riportare gli attributi così come apparivano dopo l'operazione `Update`.

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
RETURNING ALL NEW *
```

Restituisce quanto segue:

```
{
    "Items": [
        {
            "AwardDetail": {
                "M": {
                    "Grammys": {
                        "L": [
                            {
                                "N": "2020"
                            },
                            {
                                "N": "2018"
                            }
                        ]
                    }
                }
            },
            "AwardsWon": {
                "N": "1"
            }
        }
    ]
}
```

La seguente query aggiorna un elemento nella tabella `"Music"` aggiungendolo a un elenco `AwardDetail.Grammys`.

```
UPDATE "Music" 
SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

La seguente query aggiorna un elemento nella tabella `"Music"` rimuovendolo da un elenco `AwardDetail.Grammys`.

```
UPDATE "Music" 
REMOVE AwardDetail.Grammys[2]   
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

La seguente query aggiorna un elemento nella tabella `"Music"` aggiungendo `BillBoard` alla mappa `AwardDetail`.

```
UPDATE "Music" 
SET AwardDetail.BillBoard=[2020] 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

La seguente query aggiorna un elemento nella tabella `"Music"` aggiungendo l'attributo del set di stringhe `BandMembers`.

```
UPDATE "Music" 
SET BandMembers =<<'member1', 'member2'>> 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

La seguente query aggiorna un elemento nella tabella `"Music"` aggiungendo `newbandmember` al set di stringhe `BandMembers`.

```
UPDATE "Music" 
SET BandMembers =set_add(BandMembers, <<'newbandmember'>>) 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

# Istruzioni DELETE PartiQL per DynamoDB
<a name="ql-reference.delete"></a>

Utilizza l'istruzione `DELETE` per eliminare un elemento esistente dalla tabella Amazon DynamoDB.

**Nota**  
È possibile eliminare un solo elemento alla volta. Non è possibile emettere una singola istruzione DynamoDB PartiQL che elimina più elementi. Per informazioni sull'aggiornamento di più elementi, consulta [Esecuzione di transazioni con PartiQL per DynamoDB](ql-reference.multiplestatements.transactions.md) o [Esecuzione di operazioni in batch con PartiQL per DynamoDB](ql-reference.multiplestatements.batching.md).

**Topics**
+ [

## Sintassi
](#ql-reference.delete.syntax)
+ [

## Parameters
](#ql-reference.delete.parameters)
+ [

## Valore restituito
](#ql-reference.delete.return)
+ [

## Esempi
](#ql-reference.delete.examples)

## Sintassi
<a name="ql-reference.delete.syntax"></a>

```
DELETE FROM table 
 WHERE condition [RETURNING returnvalues]
 <returnvalues>  ::= ALL OLD *
```

## Parameters
<a name="ql-reference.delete.parameters"></a>

***table***  
(Obbligatorio) La tabella DynamoDB contenente l'elemento da eliminare.

***condition***  
(Obbligatorio) I criteri di selezione per l'elemento da eliminare. Questa condizione deve essere risolta in un singolo valore di chiave primaria.

***returnvalues***  
(Facoltativo) Utilizza `returnvalues` se desideri ottenere gli attributi dell'elemento come apparivano prima dell'eliminazione. I valori validi sono:   
+ `ALL OLD *`: viene restituito il contenuto del vecchio elemento.

## Valore restituito
<a name="ql-reference.delete.return"></a>

Questa istruzione non restituisce un valore a meno che non sia stato specificato il parametro `returnvalues`.

**Nota**  
Se la tabella DynamoDB non dispone di alcun elemento con la stessa chiave primaria di quella dell'elemento per il quale viene emessa l'istruzione DELETE (ELIMINA), viene restituito SUCCESS (ESITO POSITIVO) con 0 elementi eliminati. Se la tabella ha un elemento con la stessa chiave primaria, ma la condizione nella clausola WHERE (DOVE) dell'istruzione DELETE (ELIMINA) restituisce valore false, viene restituito il parametro `ConditionalCheckFailedException`.

## Esempi
<a name="ql-reference.delete.examples"></a>

La query seguente elimina un elemento nella tabella `"Music"`.

```
DELETE FROM "Music" WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks'
```

È possibile aggiungere il parametro `RETURNING ALL OLD *` per restituire i dati che sono stati eliminati.

```
DELETE FROM "Music" WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks' RETURNING ALL OLD *
```

L'istruzione `Delete` ora restituisce quanto segue:

```
{
    "Items": [
        {
            "Artist": {
                "S": "Acme Band"
            },
            "SongTitle": {
                "S": "PartiQL Rocks"
            }
        }
    ]
}
```

# Istruzioni INSERT PartiQL per DynamoDB
<a name="ql-reference.insert"></a>

Utilizza l'istruzione `INSERT` per aggiungere un elemento a una tabella in Amazon DynamoDB.

**Nota**  
È possibile inserire un solo elemento alla volta; non è possibile emettere una singola istruzione PartiQL DynamoDB che inserisce più elementi. Per informazioni sull'inserimento di più elementi, consulta [Esecuzione di transazioni con PartiQL per DynamoDB](ql-reference.multiplestatements.transactions.md) o [Esecuzione di operazioni in batch con PartiQL per DynamoDB](ql-reference.multiplestatements.batching.md).

**Topics**
+ [

## Sintassi
](#ql-reference.insert.syntax)
+ [

## Parameters
](#ql-reference.insert.parameters)
+ [

## Valore restituito
](#ql-reference.insert.return)
+ [

## Esempi
](#ql-reference.insert.examples)

## Sintassi
<a name="ql-reference.insert.syntax"></a>

Inserisci un singolo elemento.

```
INSERT INTO table VALUE item
```

## Parameters
<a name="ql-reference.insert.parameters"></a>

***table***  
(Obbligatorio) La tabella in cui si desidera inserire i dati. La tabella deve già essere presente.

***item***  
(Obbligatorio) Un elemento DynamoDB valido rappresentato come [tupla PartiQL](https://partiql.org/docs.html). È necessario specificare solo *un* elemento e tenere presente che ciascun nome di attributo nell'elemento fa distinzione tra maiuscole e minuscole e può essere riportato con virgolette *singole* (`'...'`) in PartiQL.  
Anche i valori stringa sono riportati con virgolette *singole* (`'...'`) in PartiQL.

## Valore restituito
<a name="ql-reference.insert.return"></a>

Questa istruzione non restituisce alcun valore.

**Nota**  
Se nella tabella DynamoDB è già presente un elemento con la stessa chiave primaria della chiave primaria dell'elemento da inserire, viene restituito `DuplicateItemException`.

## Esempi
<a name="ql-reference.insert.examples"></a>

```
INSERT INTO "Music" value {'Artist' : 'Acme Band','SongTitle' : 'PartiQL Rocks'}
```

# Utilizzo delle funzioni PartiQL con DynamoDB
<a name="ql-functions"></a>

PartiQL in Amazon DynamoDB supporta le seguenti varianti incorporate di funzioni standard SQL.

**Nota**  
Tutte le funzioni SQL non incluse in questo elenco non sono attualmente supportate in DynamoDB.

## Funzioni di aggregazione
<a name="ql-functions.aggregate"></a>
+ [Utilizzo della funzione SIZE con PartiQL per Amazon DynamoDB](ql-functions.size.md)

## Funzioni condizionali
<a name="ql-functions.conditional"></a>
+ [Utilizzo della funzione EXISTS con PartiQL per DynamoDB](ql-functions.exists.md)
+ [Utilizzo della funzione ATTRIBUTE\$1TYPE con PartiQL per DynamoDB](ql-functions.attribute_type.md)
+ [Utilizzo della funzione BEGINS\$1WITH con PartiQL per DynamoDB](ql-functions.beginswith.md)
+ [Utilizzo della funzione CONTAINS con PartiQL per DynamoDB](ql-functions.contains.md)
+ [Utilizzo della funzione MISSING con PartiQL per DynamoDB](ql-functions.missing.md)

# Utilizzo della funzione EXISTS con PartiQL per DynamoDB
<a name="ql-functions.exists"></a>

È possibile utilizzare EXISTS (ESISTE) per eseguire la stessa funzione che `ConditionCheck` esegue nell'API [TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems). La funzione EXISTS (ESISTE) può essere utilizzata solo nelle transazioni.

Dato un valore, restituisce `TRUE` se il valore è una raccolta non vuota. In caso contrario, restituisce `FALSE`.

**Nota**  
Questa funzione può essere utilizzata solo nelle operazioni transazionali.

## Sintassi
<a name="ql-functions.exists.syntax"></a>

```
EXISTS ( statement )
```

## Argomenti
<a name="ql-functions.exists.arguments"></a>

*Istruzione*  
(Obbligatorio) L'istruzione SELECT (SELEZIONA) valutata dalla funzione.  
L'istruzione SELECT (SELEZIONA) deve specificare una chiave primaria completa e un'altra condizione.

## Tipo restituito
<a name="ql-functions.exists.return-type"></a>

`bool`

## Esempi
<a name="ql-functions.exists.examples"></a>

```
EXISTS(
    SELECT * FROM "Music" 
    WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks')
```

# Utilizzo della funzione BEGINS\$1WITH con PartiQL per DynamoDB
<a name="ql-functions.beginswith"></a>

Restituisce `TRUE` se l'attributo specificato inizia con una particolare sottostringa.

## Sintassi
<a name="ql-functions.beginswith.syntax"></a>

```
begins_with(path, value )
```

## Argomenti
<a name="ql-functions.beginswith.arguments"></a>

*path*  
(Obbligatorio) Il nome attributo o il percorso del documento da utilizzare.

*value*  
(Obbligatorio) La stringa da cercare.

## Tipo restituito
<a name="ql-functions.beginswith.return-type"></a>

`bool`

## Esempi
<a name="ql-functions.beginswith.examples"></a>

```
SELECT * FROM "Orders" WHERE "OrderID"=1 AND begins_with("Address", '7834 24th')
```

# Utilizzo della funzione MISSING con PartiQL per DynamoDB
<a name="ql-functions.missing"></a>

Restituisce `TRUE` se l'elemento non contiene l'attributo specificato. Con questa funzione possono essere utilizzati solo gli operatori di uguaglianza e disuguaglianza.

## Sintassi
<a name="ql-functions.missing.syntax"></a>

```
 attributename IS | IS NOT  MISSING 
```

## Argomenti
<a name="ql-functions.missing.arguments"></a>

*attributename*  
(Obbligatorio) Il nome dell'attributo da utilizzare.

## Tipo restituito
<a name="ql-functions.missing.return-type"></a>

`bool`

## Esempi
<a name="ql-functions.missing.examples"></a>

```
SELECT * FROM Music WHERE "Awards" is MISSING
```

# Utilizzo della funzione ATTRIBUTE\$1TYPE con PartiQL per DynamoDB
<a name="ql-functions.attribute_type"></a>

Restituisce `TRUE` se l'attributo del percorso specificato è di un particolare tipo di dati.

## Sintassi
<a name="ql-functions.attribute_type.syntax"></a>

```
attribute_type( attributename, type )
```

## Argomenti
<a name="ql-functions.attribute_type.arguments"></a>

*attributename*  
(Obbligatorio) Il nome dell'attributo da utilizzare.

*tipo*  
(Obbligatorio) Il tipo di attributo da controllare. Per visualizzare un elenco di valori validi, consulta [attribute\$1type](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) di DynamoDB.

## Tipo restituito
<a name="ql-functions.attribute_type.return-type"></a>

`bool`

## Esempi
<a name="ql-functions.attribute_type.examples"></a>

```
SELECT * FROM "Music" WHERE attribute_type("Artist", 'S')
```

# Utilizzo della funzione CONTAINS con PartiQL per DynamoDB
<a name="ql-functions.contains"></a>

Restituisce `TRUE` se l'attributo specificato dal percorso è uno dei seguenti:
+ Una stringa che contiene una particolare sottostringa. 
+ Un set che contiene un particolare determinato elemento.

Per ulteriori informazioni, consulta la funzione [contains](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) di DynamoDB. 

## Sintassi
<a name="ql-functions.contains.syntax"></a>

```
contains( path, substring )
```

## Argomenti
<a name="ql-functions.contains.arguments"></a>

*path*  
(Obbligatorio) Il nome attributo o il percorso del documento da utilizzare.

*sottostringa*  
(Obbligatorio) La sottostringa dell'attributo o il membro del set da controllare. Per ulteriori informazioni, consulta la funzione [contains](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) di DynamoDB.

## Tipo restituito
<a name="ql-functions.contains.return-type"></a>

`bool`

## Esempi
<a name="ql-functions.contains.examples"></a>

```
SELECT * FROM "Orders" WHERE "OrderID"=1 AND contains("Address", 'Kirkland')
```

# Utilizzo della funzione SIZE con PartiQL per Amazon DynamoDB
<a name="ql-functions.size"></a>

Restituisce un numero che rappresenta le dimensioni di un attributo (in byte). I seguenti sono tipi di dati validi per l'utilizzo con size. Per ulteriori informazioni, consulta la funzione [size](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) di DynamoDB.

## Sintassi
<a name="ql-functions.size.syntax"></a>

```
size( path)
```

## Argomenti
<a name="ql-functions.size.arguments"></a>

*path*  
(Obbligatorio) Il nome attributo o il percorso del documento.   
Per i tipi supportati, consulta la funzione [size](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) di DynamoDB.

## Tipo restituito
<a name="ql-functions.size.return-type"></a>

`int`

## Esempi
<a name="ql-functions.size.examples"></a>

```
 SELECT * FROM "Orders" WHERE "OrderID"=1 AND size("Image") >300
```

# Operatori PartiQL aritmetici, di confronto e logici per DynamoDB
<a name="ql-operators"></a>

PartiQL in Amazon DynamoDB supporta i seguenti [operatori SQL standard](https://www.w3schools.com/sql/sql_operators.asp).

**Nota**  
Tutti gli operatori SQL che non sono inclusi in questo elenco non sono attualmente supportati in DynamoDB.

## Operatori aritmetici
<a name="ql-operators.arithmetic"></a>


****  

| Operatore | Description | 
| --- | --- | 
| \$1 | Add (Aggiungi) | 
| - | Subtract | 

## Operatori di confronto
<a name="ql-operators.comparison"></a>


****  

| Operatore | Description | 
| --- | --- | 
| = | Equal to | 
| <> | Not Equal to | 
| \$1= | Not Equal to | 
| > | Greater than | 
| < | Less than | 
| >= | Greater than or equal to | 
| <= | Less than or equal to | 

## Operatori logici
<a name="ql-operators.logical"></a>


****  

| Operatore | Description | 
| --- | --- | 
| AND | TRUE se tutte le condizioni separate da AND sono TRUE | 
| BETWEEN |  `TRUE` se l’operando è all’interno dell’intervallo di confronti. Questo operatore include il limite inferiore e superiore degli operandi su cui viene applicato.  | 
| IN | `TRUE`se l'operando è uguale a uno di un elenco di espressioni (con un massimo di 50 valori di attributi hash o un massimo di 100 valori di attributi non chiave). I risultati vengono restituiti in pagine contenenti un massimo di 10 elementi. Se l'`IN`elenco contiene più valori, è necessario utilizzare quello `NextToken` restituito nella risposta per recuperare le pagine successive. | 
| IS | TRUE se l'operando è un dato tipo di dati PartiQL, inclusoNULL o MISSING | 
| NOT | Inverte il valore di una determinata espressione booleana | 
| OR | TRUE se una delle condizioni separate da OR è TRUE | 

Per ulteriori informazioni sull’utilizzo degli operatori logici, consulta [Realizzazione di confronti](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.Comparators) e [Valutazioni logiche](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.LogicalEvaluations).

# Esecuzione di transazioni con PartiQL per DynamoDB
<a name="ql-reference.multiplestatements.transactions"></a>

In questa sezione viene descritto come utilizzare le transazioni con PartiQL per DynamoDB. Le transazioni PartiQL sono limitate a 100 istruzioni totali (operazioni).

Per ulteriori informazioni sulle transazioni DynamoDB, consulta [Gestione di flussi di lavoro complessi con transazioni DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html).

**Nota**  
L'intera transazione deve essere costituita da istruzioni di lettura o di scrittura. Non puoi combinare entrambe in un'unica transazione. La funzione EXISTS è un'eccezione. È possibile utilizzarlo per verificare la condizione degli attributi specifici dell'elemento in modo simile al funzionamento `ConditionCheck` dell'[TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems)API.

**Topics**
+ [

## Sintassi
](#ql-reference.multiplestatements.transactions.syntax)
+ [

## Parameters
](#ql-reference.multiplestatements.transactions.parameters)
+ [

## Valori restituiti
](#ql-reference.multiplestatements.transactions.return)
+ [

## Esempi
](#ql-reference.multiplestatements.transactions.examples)

## Sintassi
<a name="ql-reference.multiplestatements.transactions.syntax"></a>

```
[
   {
      "Statement":" statement ",
      "Parameters":[
         {
            " parametertype " : " parametervalue "
         }, ...]
   } , ...
]
```

## Parameters
<a name="ql-reference.multiplestatements.transactions.parameters"></a>

***statement***  
(Obbligatorio) Un'istruzione supportata PartiQL per DynamoDB.  
L'intera transazione deve essere costituita da istruzioni di lettura o di scrittura. Non puoi combinare entrambe in un'unica transazione.

***parametertype***  
(Facoltativo) Un tipo DynamoDB, se durante la specifica dell'istruzione PartiQL sono stati utilizzati dei parametri.

***parametervalue***  
(Facoltativo) Il valore di un parametro se durante la specifica dell'istruzione PartiQL sono stati utilizzati dei parametri.

## Valori restituiti
<a name="ql-reference.multiplestatements.transactions.return"></a>

Questa istruzione non restituisce alcun valore per le operazioni di scrittura (INSERT, UPDATE o DELETE). Tuttavia, restituisce valori diversi per le operazioni di lettura (SELECT) in base alle condizioni specificate nella clausola WHERE.

**Nota**  
Se una qualsiasi delle singole operazioni INSERT, UPDATE o DELETE restituisce un errore, le transazioni verranno annullate con l'eccezione `TransactionCanceledException` e il codice motivo dell'annullamento includerà gli errori delle singole operazioni.

## Esempi
<a name="ql-reference.multiplestatements.transactions.examples"></a>

L'esempio seguente esegue più istruzioni come transazione.

------
#### [ AWS CLI ]

1. Salva il codice JSON seguente in un file chiamato partiql.json. 

   ```
   [
       {
           "Statement": "EXISTS(SELECT * FROM \"Music\" where Artist='No One You Know' and SongTitle='Call Me Today' and Awards is  MISSING)"
       },
       {
           "Statement": "INSERT INTO Music value {'Artist':?,'SongTitle':'?'}",
           "Parameters": [{\"S\": \"Acme Band\"}, {\"S\": \"Best Song\"}]
       },
       {
           "Statement": "UPDATE \"Music\" SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]}  where Artist='Acme Band' and SongTitle='PartiQL Rocks'"
       }
   ]
   ```

1. Esegui il comando seguente al prompt dei comandi.

   ```
   aws dynamodb execute-transaction --transact-statements  file://partiql.json
   ```

------
#### [ Java ]

```
public class DynamoDBPartiqlTransaction {

    public static void main(String[] args) {
        // Create the DynamoDB Client with the region you want
        AmazonDynamoDB dynamoDB = createDynamoDbClient("us-west-2");
        
        try {
            // Create ExecuteTransactionRequest
            ExecuteTransactionRequest executeTransactionRequest = createExecuteTransactionRequest();
            ExecuteTransactionResult executeTransactionResult = dynamoDB.executeTransaction(executeTransactionRequest);
            System.out.println("ExecuteTransaction successful.");
            // Handle executeTransactionResult

        } catch (Exception e) {
            handleExecuteTransactionErrors(e);
        }
    }

    private static AmazonDynamoDB createDynamoDbClient(String region) {
        return AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
    }

    private static ExecuteTransactionRequest createExecuteTransactionRequest() {
        ExecuteTransactionRequest request = new ExecuteTransactionRequest();
        
        // Create statements
        List<ParameterizedStatement> statements = getPartiQLTransactionStatements();

        request.setTransactStatements(statements);
        return request;
    }

    private static List<ParameterizedStatement> getPartiQLTransactionStatements() {
        List<ParameterizedStatement> statements = new ArrayList<ParameterizedStatement>();

        statements.add(new ParameterizedStatement()
                               .withStatement("EXISTS(SELECT * FROM "Music" where Artist='No One You Know' and SongTitle='Call Me Today' and Awards is  MISSING)"));

        statements.add(new ParameterizedStatement()
                               .withStatement("INSERT INTO "Music" value {'Artist':'?','SongTitle':'?'}")
                               .withParameters(new AttributeValue("Acme Band"),new AttributeValue("Best Song")));

        statements.add(new ParameterizedStatement()
                               .withStatement("UPDATE "Music" SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]}  where Artist='Acme Band' and SongTitle='PartiQL Rocks'"));

        return statements;
    }

    // Handles errors during ExecuteTransaction execution. Use recommendations in error messages below to add error handling specific to 
    // your application use-case.
    private static void handleExecuteTransactionErrors(Exception exception) {
        try {
            throw exception;
        } catch (TransactionCanceledException tce) {
            System.out.println("Transaction Cancelled, implies a client issue, fix before retrying. Error: " + tce.getErrorMessage());
        } catch (TransactionInProgressException tipe) {
            System.out.println("The transaction with the given request token is already in progress, consider changing " +
                "retry strategy for this type of error. Error: " + tipe.getErrorMessage());
        } catch (IdempotentParameterMismatchException ipme) {
            System.out.println("Request rejected because it was retried with a different payload but with a request token that was already used, " +
                "change request token for this payload to be accepted. Error: " + ipme.getErrorMessage());
        } catch (Exception e) {
            handleCommonErrors(e);
        }
    }

    private static void handleCommonErrors(Exception exception) {
        try {
            throw exception;
        } catch (InternalServerErrorException isee) {
            System.out.println("Internal Server Error, generally safe to retry with exponential back-off. Error: " + isee.getErrorMessage());
        } catch (RequestLimitExceededException rlee) {
            System.out.println("Throughput exceeds the current throughput limit for your account, increase account level throughput before " + 
                "retrying. Error: " + rlee.getErrorMessage());
        } catch (ProvisionedThroughputExceededException ptee) {
            System.out.println("Request rate is too high. If you're using a custom retry strategy make sure to retry with exponential back-off. " +
                "Otherwise consider reducing frequency of requests or increasing provisioned capacity for your table or secondary index. Error: " + 
                ptee.getErrorMessage());
        } catch (ResourceNotFoundException rnfe) {
            System.out.println("One of the tables was not found, verify table exists before retrying. Error: " + rnfe.getErrorMessage());
        } catch (AmazonServiceException ase) {
            System.out.println("An AmazonServiceException occurred, indicates that the request was correctly transmitted to the DynamoDB " + 
                "service, but for some reason, the service was not able to process it, and returned an error response instead. Investigate and " +
                "configure retry strategy. Error type: " + ase.getErrorType() + ". Error message: " + ase.getErrorMessage());
        } catch (AmazonClientException ace) {
            System.out.println("An AmazonClientException occurred, indicates that the client was unable to get a response from DynamoDB " +
                "service, or the client was unable to parse the response from the service. Investigate and configure retry strategy. "+
                "Error: " + ace.getMessage());
        } catch (Exception e) {
            System.out.println("An exception occurred, investigate and configure retry strategy. Error: " + e.getMessage());
        }
    }

}
```

------

L'esempio seguente mostra i diversi valori restituiti quando DynamoDB legge elementi con condizioni diverse specificate nella clausola WHERE.

------
#### [ AWS CLI ]

1. Salva il codice JSON seguente in un file chiamato partiql.json.

   ```
   [
       // Item exists and projected attribute exists
       {
           "Statement": "SELECT * FROM "Music" WHERE Artist='No One You Know' and SongTitle='Call Me Today'"
       },
       // Item exists but projected attributes do not exist
       {
           "Statement": "SELECT non_existent_projected_attribute FROM "Music" WHERE Artist='No One You Know' and SongTitle='Call Me Today'"
       },
       // Item does not exist
       {
           "Statement": "SELECT * FROM "Music" WHERE Artist='No One I Know' and SongTitle='Call You Today'"
       }
   ]
   ```

1.  Esegui il comando seguente in un prompt dei comandi.

   ```
   aws dynamodb execute-transaction --transact-statements  file://partiql.json
   ```

1. Viene restituita la risposta seguente:

   ```
   {
       "Responses": [
           // Item exists and projected attribute exists
           {
               "Item": {
                   "Artist":{
                       "S": "No One You Know"
                   },
                   "SongTitle":{
                       "S": "Call Me Today"
                   }    
               }
           },
           // Item exists but projected attributes do not exist
           {
               "Item": {}
           },
           // Item does not exist
           {}
       ]
   }
   ```

------

# Esecuzione di operazioni in batch con PartiQL per DynamoDB
<a name="ql-reference.multiplestatements.batching"></a>

In questa sezione viene descritto come utilizzare le istruzioni in batch con PartiQL per DynamoDB.

**Nota**  
L'intera transazione deve essere costituita da istruzioni di lettura o di scrittura; non è possibile combinare entrambe le istruzioni in un batch.
`BatchExecuteStatement` e `BatchWriteItem` possono eseguire al massimo 25 istruzioni per batch.
`BatchExecuteStatement` utilizza `BatchGetItem`, che richiede un elenco di chiavi primarie in istruzioni separate.

**Topics**
+ [

## Sintassi
](#ql-reference.multiplestatements.batching.syntax)
+ [

## Parameters
](#ql-reference.multiplestatements.batching.parameters)
+ [

## Esempi
](#ql-reference.multiplestatements.batching.examples)

## Sintassi
<a name="ql-reference.multiplestatements.batching.syntax"></a>

```
[
  {
    "Statement": "SELECT pk FROM ProblemSet WHERE pk = 'p#9StkWHYTxm7x2AqSXcrfu7' AND sk = 'info'"
  },
  {
    "Statement": "SELECT pk FROM ProblemSet WHERE pk = 'p#isC2ChceGbxHgESc4szoTE' AND sk = 'info'"
  }
]
```

```
[
   {
      "Statement":" statement ",
      "Parameters":[
         {
            " parametertype " : " parametervalue "
         }, ...]
   } , ...
]
```

## Parameters
<a name="ql-reference.multiplestatements.batching.parameters"></a>

***statement***  
(Obbligatorio) Un'istruzione supportata PartiQL per DynamoDB.  
+ L'intera transazione deve essere costituita da istruzioni di lettura o di scrittura; non è possibile combinare entrambe le istruzioni in un batch.
+ `BatchExecuteStatement` e `BatchWriteItem` possono eseguire al massimo 25 istruzioni per batch.

***parametertype***  
(Facoltativo) Un tipo DynamoDB, se durante la specifica dell'istruzione PartiQL sono stati utilizzati dei parametri.

***parametervalue***  
(Facoltativo) Il valore di un parametro se durante la specifica dell'istruzione PartiQL sono stati utilizzati dei parametri.

## Esempi
<a name="ql-reference.multiplestatements.batching.examples"></a>

------
#### [ AWS CLI ]

1. Salvataggio del JSON seguente in un file chiamato partiql.json

   ```
   [
      {
   	 "Statement": "INSERT INTO Music VALUE {'Artist':?,'SongTitle':?}",
   	  "Parameters": [{"S": "Acme Band"}, {"S": "Best Song"}]
   	},
   	{
   	 "Statement": "UPDATE Music SET AwardsWon=1, AwardDetail={'Grammys':[2020, 2018]} WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
       }
   ]
   ```

1. Esegui il comando seguente al prompt dei comandi.

   ```
   aws dynamodb batch-execute-statement  --statements  file://partiql.json
   ```

------
#### [ Java ]

```
public class DynamoDBPartiqlBatch {

    public static void main(String[] args) {
        // Create the DynamoDB Client with the region you want
        AmazonDynamoDB dynamoDB = createDynamoDbClient("us-west-2");
        
        try {
            // Create BatchExecuteStatementRequest
            BatchExecuteStatementRequest batchExecuteStatementRequest = createBatchExecuteStatementRequest();
            BatchExecuteStatementResult batchExecuteStatementResult = dynamoDB.batchExecuteStatement(batchExecuteStatementRequest);
            System.out.println("BatchExecuteStatement successful.");
            // Handle batchExecuteStatementResult

        } catch (Exception e) {
            handleBatchExecuteStatementErrors(e);
        }
    }

    private static AmazonDynamoDB createDynamoDbClient(String region) {

        return AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
    }

    private static BatchExecuteStatementRequest createBatchExecuteStatementRequest() {
        BatchExecuteStatementRequest request = new BatchExecuteStatementRequest();

        // Create statements
        List<BatchStatementRequest> statements = getPartiQLBatchStatements();

        request.setStatements(statements);
        return request;
    }

    private static List<BatchStatementRequest> getPartiQLBatchStatements() {
        List<BatchStatementRequest> statements = new ArrayList<BatchStatementRequest>();

        statements.add(new BatchStatementRequest()
                               .withStatement("INSERT INTO Music value {'Artist':'Acme Band','SongTitle':'PartiQL Rocks'}"));

        statements.add(new BatchStatementRequest()
                               .withStatement("UPDATE Music set AwardDetail.BillBoard=[2020] where Artist='Acme Band' and SongTitle='PartiQL Rocks'"));

        return statements;
    }

    // Handles errors during BatchExecuteStatement execution. Use recommendations in error messages below to add error handling specific to 
    // your application use-case.
    private static void handleBatchExecuteStatementErrors(Exception exception) {
        try {
            throw exception;
        } catch (Exception e) {
            // There are no API specific errors to handle for BatchExecuteStatement, common DynamoDB API errors are handled below
            handleCommonErrors(e);
        }
    }

    private static void handleCommonErrors(Exception exception) {
        try {
            throw exception;
        } catch (InternalServerErrorException isee) {
            System.out.println("Internal Server Error, generally safe to retry with exponential back-off. Error: " + isee.getErrorMessage());
        } catch (RequestLimitExceededException rlee) {
            System.out.println("Throughput exceeds the current throughput limit for your account, increase account level throughput before " + 
                "retrying. Error: " + rlee.getErrorMessage());
        } catch (ProvisionedThroughputExceededException ptee) {
            System.out.println("Request rate is too high. If you're using a custom retry strategy make sure to retry with exponential back-off. " +
                "Otherwise consider reducing frequency of requests or increasing provisioned capacity for your table or secondary index. Error: " + 
                ptee.getErrorMessage());
        } catch (ResourceNotFoundException rnfe) {
            System.out.println("One of the tables was not found, verify table exists before retrying. Error: " + rnfe.getErrorMessage());
        } catch (AmazonServiceException ase) {
            System.out.println("An AmazonServiceException occurred, indicates that the request was correctly transmitted to the DynamoDB " + 
                "service, but for some reason, the service was not able to process it, and returned an error response instead. Investigate and " +
                "configure retry strategy. Error type: " + ase.getErrorType() + ". Error message: " + ase.getErrorMessage());
        } catch (AmazonClientException ace) {
            System.out.println("An AmazonClientException occurred, indicates that the client was unable to get a response from DynamoDB " +
                "service, or the client was unable to parse the response from the service. Investigate and configure retry strategy. "+
                "Error: " + ace.getMessage());
        } catch (Exception e) {
            System.out.println("An exception occurred, investigate and configure retry strategy. Error: " + e.getMessage());
        }
    }

}
```

------

# Policy di sicurezza IAM con PartiQL per DynamoDB
<a name="ql-iam"></a>

Sono richieste le seguenti autorizzazioni:
+ Per leggere gli elementi utilizzando PartiQL per DynamoDB, è necessario disporre dell'autorizzazione `dynamodb:PartiQLSelect` sulla tabella o sull'indice.
+ Per inserire gli elementi utilizzando PartiQL per DynamoDB, è necessario disporre dell'autorizzazione `dynamodb:PartiQLInsert` sulla tabella o sull'indice.
+ Per aggiornare gli elementi utilizzando PartiQL per DynamoDB, è necessario disporre dell'autorizzazione `dynamodb:PartiQLUpdate` sulla tabella o sull'indice.
+ Per inserire gli elementi utilizzando PartiQL per DynamoDB, è necessario disporre dell'autorizzazione `dynamodb:PartiQLDelete` sulla tabella o sull'indice.

## Esempio: consentire tutte le istruzioni PartiQL for DynamoDB () su una tabella Select/Insert/Update/Delete
<a name="access-policy-ql-iam-example1"></a>

La seguente policy IAM concede le autorizzazioni per eseguire tutte le istruzioni PartiQL per DynamoDB su una tabella specifica. 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ]
      }
   ]
}
```

------

## Esempio: Consentire le istruzioni SELECT (SELEZIONA) PartiQL per DynamoDB su una tabella
<a name="access-policy-ql-iam-example2"></a>

La seguente policy IAM concede le autorizzazioni per eseguire l'istruzione `select` su una tabella specifica.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ]
      }
   ]
}
```

------

## Esempio: Consentire le istruzioni INSERT PartiQL per DynamoDB su un indice
<a name="access-policy-ql-iam-example3"></a>

La seguente policy IAM concede le autorizzazioni per eseguire l'istruzione `insert` su un indice specifico. 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music/index/index1"
         ]
      }
   ]
}
```

------

## Esempio: Consentire le istruzioni transazionali PartiQL per DynamoDB solo su una tabella
<a name="access-policy-ql-iam-example4"></a>

La seguente policy IAM concede le autorizzazioni per eseguire le istruzioni transazionali su una tabella specifica. 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ],
         "Condition":{
            "StringEquals":{
               "dynamodb:EnclosingOperation":[
                  "ExecuteTransaction"
               ]
            }
         }
      }
   ]
}
```

------

## Esempio: Consentire letture e scritture non transazionali di PartiQL per DynamoDB e bloccare le istruzioni transazionali di letture e scritture transazionali di PartiQL su una tabella.
<a name="access-policy-ql-iam-example5"></a>

 La seguente policy IAM concede le autorizzazioni per eseguire letture e le scritture non transazionali PartiQL per DynamoDB bloccando le letture e le scritture transazionali PartiQL per DynamoDB.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Deny",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ],
         "Condition":{
            "StringEquals":{
               "dynamodb:EnclosingOperation":[
                  "ExecuteTransaction"
               ]
            }
         }
      },
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ]
      }
   ]
}
```

------

## Esempio: Consentire le istruzioni Select e rifiutare le istruzioni di scansione completa della tabella in PartiQL per DynamoDB
<a name="access-policy-ql-iam-example6"></a>

La seguente policy IAM concede le autorizzazioni per eseguire l'istruzione `select` su una tabella specifica durante il blocco delle istruzioni `select` che determinano una scansione completa della tabella.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Deny",
         "Action":[
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/WatchList"
         ],
         "Condition":{
            "Bool":{
               "dynamodb:FullTableScan":[
                  "true"
               ]
            }
         }
      },
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/WatchList"
         ]
      }
   ]
}
```

------

# Utilizzo degli elementi: Java
<a name="JavaDocumentAPIItemCRUD"></a>

Puoi utilizzare l'API AWS SDK per Java Document per eseguire operazioni tipiche di creazione, lettura, aggiornamento ed eliminazione (CRUD) sugli elementi di Amazon DynamoDB in una tabella.

**Nota**  
L'SDK per Java offre inoltre un modello di persistenza degli oggetti che permette di mappare le classi lato client alle tabelle DynamoDB. Questo approccio può ridurre la quantità di codice da scrivere. Per ulteriori informazioni, consulta [Java 1.x: Dinamo DBMapper](DynamoDBMapper.md).

Questa sezione contiene esempi Java per eseguire diverse operazioni operazioni sugli elementi dell'API documento Java e diversi esempi di lavoro completi.

**Topics**
+ [

## Collocazione di un elemento
](#PutDocumentAPIJava)
+ [

## Ottenimento di un elemento
](#JavaDocumentAPIGetItem)
+ [

## Scrittura in batch: collocazione ed eliminazione di più elementi
](#BatchWriteDocumentAPIJava)
+ [

## Ricezione in batch: ricezione di più elementi
](#JavaDocumentAPIBatchGetItem)
+ [

## Aggiornamento di un elemento
](#JavaDocumentAPIItemUpdate)
+ [

## Eliminazione di un elemento
](#DeleteMidLevelJava)
+ [

# Esempio: operazioni CRUD che utilizzano l'API del documento AWS SDK per Java
](JavaDocumentAPICRUDExample.md)
+ [

# Esempio: operazioni Batch utilizzando l'API AWS SDK per Java dei documenti
](batch-operation-document-api-java.md)
+ [

# Esempio: gestione degli attributi di tipo binario utilizzando l'API del AWS SDK per Java documento
](JavaDocumentAPIBinaryTypeExample.md)

## Collocazione di un elemento
<a name="PutDocumentAPIJava"></a>

Il metodo `putItem` memorizza un item nella tabella. Se l'item esiste, lo sostituisce per intero. Se invece di sostituire l'intero item vuoi aggiornare solo attributi specifici, puoi utilizzare il metodo `updateItem`. Per ulteriori informazioni, consulta [Aggiornamento di un elemento](#JavaDocumentAPIItemUpdate). 

------
#### [ Java v2 ]

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import java.util.HashMap;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * To place items into an Amazon DynamoDB table using the AWS SDK for Java V2,
 * its better practice to use the
 * Enhanced Client. See the EnhancedPutItem example.
 */
public class PutItem {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <tableName> <key> <keyVal> <albumtitle> <albumtitleval> <awards> <awardsval> <Songtitle> <songtitleval>

                Where:
                    tableName - The Amazon DynamoDB table in which an item is placed (for example, Music3).
                    key - The key used in the Amazon DynamoDB table (for example, Artist).
                    keyval - The key value that represents the item to get (for example, Famous Band).
                    albumTitle - The Album title (for example, AlbumTitle).
                    AlbumTitleValue - The name of the album (for example, Songs About Life ).
                    Awards - The awards column (for example, Awards).
                    AwardVal - The value of the awards (for example, 10).
                    SongTitle - The song title (for example, SongTitle).
                    SongTitleVal - The value of the song title (for example, Happy Day).
                **Warning** This program will  place an item that you specify into a table!
                """;

        if (args.length != 9) {
            System.out.println(usage);
            System.exit(1);
        }

        String tableName = args[0];
        String key = args[1];
        String keyVal = args[2];
        String albumTitle = args[3];
        String albumTitleValue = args[4];
        String awards = args[5];
        String awardVal = args[6];
        String songTitle = args[7];
        String songTitleVal = args[8];

        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        putItemInTable(ddb, tableName, key, keyVal, albumTitle, albumTitleValue, awards, awardVal, songTitle,
                songTitleVal);
        System.out.println("Done!");
        ddb.close();
    }

    public static void putItemInTable(DynamoDbClient ddb,
            String tableName,
            String key,
            String keyVal,
            String albumTitle,
            String albumTitleValue,
            String awards,
            String awardVal,
            String songTitle,
            String songTitleVal) {

        HashMap<String, AttributeValue> itemValues = new HashMap<>();
        itemValues.put(key, AttributeValue.builder().s(keyVal).build());
        itemValues.put(songTitle, AttributeValue.builder().s(songTitleVal).build());
        itemValues.put(albumTitle, AttributeValue.builder().s(albumTitleValue).build());
        itemValues.put(awards, AttributeValue.builder().s(awardVal).build());

        PutItemRequest request = PutItemRequest.builder()
                .tableName(tableName)
                .item(itemValues)
                .build();

        try {
            PutItemResponse response = ddb.putItem(request);
            System.out.println(tableName + " was successfully updated. The request id is "
                    + response.responseMetadata().requestId());

        } catch (ResourceNotFoundException e) {
            System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName);
            System.err.println("Be sure that it exists and that you've typed its name correctly!");
            System.exit(1);
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
}
```

------
#### [ Java v1 ]

Completare la procedura riportata di seguito. 

1. Creare un'istanza della classe `DynamoDB`.

1. Crea un'istanza della classe `Table` per rappresentare la tabella con cui vuoi lavorare.

1. Crea un'istanza della classe `Item` per rappresentare il nuovo item. Devi specificare la chiave primaria del nuovo item e gli attributi.

1. Chiama il metodo `putItem` dell'oggetto `Table` usando l'elemento `Item` creato nella fase precedente.

Il seguente esempio di codice Java mostra le attività precedenti. Il codice scrive un nuovo item nella tabella `ProductCatalog`.

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

// Build a list of related items
List<Number> relatedItems = new ArrayList<Number>();
relatedItems.add(341);
relatedItems.add(472);
relatedItems.add(649);

//Build a map of product pictures
Map<String, String> pictures = new HashMap<String, String>();
pictures.put("FrontView", "http://example.com/products/123_front.jpg");
pictures.put("RearView", "http://example.com/products/123_rear.jpg");
pictures.put("SideView", "http://example.com/products/123_left_side.jpg");

//Build a map of product reviews
Map<String, List<String>> reviews = new HashMap<String, List<String>>();

List<String> fiveStarReviews = new ArrayList<String>();
fiveStarReviews.add("Excellent! Can't recommend it highly enough!  Buy it!");
fiveStarReviews.add("Do yourself a favor and buy this");
reviews.put("FiveStar", fiveStarReviews);

List<String> oneStarReviews = new ArrayList<String>();
oneStarReviews.add("Terrible product!  Do not buy this.");
reviews.put("OneStar", oneStarReviews);

// Build the item
Item item = new Item()
    .withPrimaryKey("Id", 123)
    .withString("Title", "Bicycle 123")
    .withString("Description", "123 description")
    .withString("BicycleType", "Hybrid")
    .withString("Brand", "Brand-Company C")
    .withNumber("Price", 500)
    .withStringSet("Color",  new HashSet<String>(Arrays.asList("Red", "Black")))
    .withString("ProductCategory", "Bicycle")
    .withBoolean("InStock", true)
    .withNull("QuantityOnHand")
    .withList("RelatedItems", relatedItems)
    .withMap("Pictures", pictures)
    .withMap("Reviews", reviews);

// Write the item to the table
PutItemOutcome outcome = table.putItem(item);
```

Nell'esempio precedente, l'item ha attributi scalari (`String`, `Number`, `Boolean`, `Null`), set (`String Set`) e tipi di documento (`List`, `Map`).

------

### Specifica dei parametri facoltativi
<a name="PutItemJavaDocumentAPIOptions"></a>

Insieme ai parametri richiesti, puoi anche specificare parametri opzionali per il metodo `putItem`. Ad esempio, il seguente esempio di codice Java utilizza un parametro facoltativo per specificare una condizione per il caricamento dell'item. Se la condizione specificata non è soddisfatta, genera un. AWS SDK per Java `ConditionalCheckFailedException` L'esempio di codice specifica i seguenti parametri facoltativi nel metodo `putItem`:
+ un item `ConditionExpression` che definisce le condizioni della richiesta. Il codice definisce la condizione in cui l'item esistente che ha la stessa chiave primaria viene sostituito solo se ha un attributo ISBN uguale a un valore specifico. 
+ Una mappa per `ExpressionAttributeValues` che viene usata nella condizione. In questo caso, è necessaria una sola sostituzione: il segnaposto `:val` nell'espressione della condizione viene sostituito al runtime con il valore ISBN effettivo da verificare.

Nell'esempio seguente viene aggiunto un nuovo item del libro utilizzando questi parametri facoltativi.

**Example**  

```
Item item = new Item()
    .withPrimaryKey("Id", 104)
    .withString("Title", "Book 104 Title")
    .withString("ISBN", "444-4444444444")
    .withNumber("Price", 20)
    .withStringSet("Authors",
        new HashSet<String>(Arrays.asList("Author1", "Author2")));

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val", "444-4444444444");

PutItemOutcome outcome = table.putItem(
    item,
    "ISBN = :val", // ConditionExpression parameter
    null,          // ExpressionAttributeNames parameter - we're not using it for this example
    expressionAttributeValues);
```

### PutItem e documenti JSON
<a name="PutItemJavaDocumentAPI.JSON"></a>

È possibile memorizzare un documento JSON come attributo in una tabella DynamoDB. Per eseguire questa operazione, usa il metodo `withJSON` di `Item`. Questo metodo analizza il documento JSON e mappa ciascun elemento a un tipo di dati DynamoDB nativo.

Supponiamo di voler memorizzare il seguente documento JSON, contenente i fornitori in grado di soddisfare gli ordini di un determinato prodotto.

**Example**  

```
{
    "V01": {
        "Name": "Acme Books",
        "Offices": [ "Seattle" ]
    },
    "V02": {
        "Name": "New Publishers, Inc.",
        "Offices": ["London", "New York"
        ]
    },
    "V03": {
        "Name": "Better Buy Books",
        "Offices": [ "Tokyo", "Los Angeles", "Sydney"
        ]
    }
}
```

Puoi utilizzare il metodo `withJSON` per memorizzarlo nella tabella `ProductCatalog`, in un attributo `Map` denominato `VendorInfo`. Il seguente codice di esempio Java dimostra come eseguire questa operazione.

```
// Convert the document into a String.  Must escape all double-quotes.
String vendorDocument = "{"
    + "    \"V01\": {"
    + "        \"Name\": \"Acme Books\","
    + "        \"Offices\": [ \"Seattle\" ]"
    + "    },"
    + "    \"V02\": {"
    + "        \"Name\": \"New Publishers, Inc.\","
    + "        \"Offices\": [ \"London\", \"New York\"" + "]" + "},"
    + "    \"V03\": {"
    + "        \"Name\": \"Better Buy Books\","
    +          "\"Offices\": [ \"Tokyo\", \"Los Angeles\", \"Sydney\""
    + "            ]"
    + "        }"
    + "    }";

Item item = new Item()
    .withPrimaryKey("Id", 210)
    .withString("Title", "Book 210 Title")
    .withString("ISBN", "210-2102102102")
    .withNumber("Price", 30)
    .withJSON("VendorInfo", vendorDocument);

PutItemOutcome outcome = table.putItem(item);
```

## Ottenimento di un elemento
<a name="JavaDocumentAPIGetItem"></a>

Per recuperare un singolo item usa il metodo `getItem` di un oggetto `Table`. Completare la procedura riportata di seguito. 

1. Creare un'istanza della classe `DynamoDB`.

1. Crea un'istanza della classe `Table` per rappresentare la tabella con cui vuoi lavorare.

1. Chiama il metodo `getItem` dell'istanza di `Table`. Devi specificare la chiave primaria dell'item che intendi recuperare.

Il seguente esempio di codice Java mostra le fasi precedenti. Il codice ottiene l'item che ha la chiave di partizione specificata.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

Item item = table.getItem("Id", 210);
```

### Specifica dei parametri facoltativi
<a name="GetItemJavaDocumentAPIOptions"></a>

Insieme ai parametri richiesti, puoi anche specificare parametri opzionali per il metodo `getItem`. Ad esempio, il seguente esempio di codice Java utilizza un metodo facoltativo per recuperare un solo elenco specifico di attributi e per specificare letture fortemente consistenti. Per ulteriori informazioni sulla lettura consistente, consulta [Coerenza di lettura di DynamoDB](HowItWorks.ReadConsistency.md).

Puoi usare un `ProjectionExpression` per recuperare solo attributi o elementi specifici, piuttosto che un intero item. Un `ProjectionExpression` può specificare attributi nidificati o di primo livello usando i percorsi dei documenti. Per ulteriori informazioni, consulta [Utilizzo di espressioni di proiezione in DynamoDB](Expressions.ProjectionExpressions.md).

I parametri del metodo `getItem` non consentono di specificare lettura coerente. Tuttavia, puoi creare un `GetItemSpec`, che fornisce l'accesso completo a tutti gli input all'operazione `GetItem` di basso livello. Il seguente esempio di codice consente di creare un `GetItemSpec` e utilizzare tale specifica come input per il metodo `getItem`.

**Example**  

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 206)
    .withProjectionExpression("Id, Title, RelatedItems[0], Reviews.FiveStar")
    .withConsistentRead(true);

Item item = table.getItem(spec);

System.out.println(item.toJSONPretty());
```

 Per stampare un `Item` in un formato leggibile, utilizza il metodo `toJSONPretty`. L'aspetto dell'output dall'esempio precedente è simile al seguente.

```
{
  "RelatedItems" : [ 341 ],
  "Reviews" : {
    "FiveStar" : [ "Excellent! Can't recommend it highly enough! Buy it!", "Do yourself a favor and buy this" ]
  },
  "Id" : 123,
  "Title" : "20-Bicycle 123"
}
```

### GetItem e documenti JSON
<a name="GetItemJavaDocumentAPI.JSON"></a>

Nella sezione [PutItem e documenti JSON](#PutItemJavaDocumentAPI.JSON), viene archiviato un documento JSON in un attributo `Map` denominato `VendorInfo`. Puoi utilizzare il metodo `getItem` per recuperare l'intero documento nel formato JSON. Oppure puoi utilizzare la notazione del percorso del documento per recuperare solo gli stessi elementi nel documento. Il seguente esempio di codice Java mostra queste tecniche.

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 210);

System.out.println("All vendor info:");
spec.withProjectionExpression("VendorInfo");
System.out.println(table.getItem(spec).toJSON());

System.out.println("A single vendor:");
spec.withProjectionExpression("VendorInfo.V03");
System.out.println(table.getItem(spec).toJSON());

System.out.println("First office location for this vendor:");
spec.withProjectionExpression("VendorInfo.V03.Offices[0]");
System.out.println(table.getItem(spec).toJSON());
```

L'aspetto dell'output dall'esempio precedente è simile al seguente.

```
All vendor info:
{"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]},"V02":{"Name":"New Publishers, Inc.","Offices":["London","New York"]},"V01":{"Name":"Acme Books","Offices":["Seattle"]}}}
A single vendor:
{"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]}}}
First office location for a single vendor:
{"VendorInfo":{"V03":{"Offices":["Tokyo"]}}}
```

**Nota**  
Puoi usare il metodo `toJSON` per convertire qualsiasi item (o gli attributi) in una stringa in formato JSON. Il seguente codice recupera diversi attributi di primo livello e nidificati e stampa i risultati come JSON.  

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 210)
    .withProjectionExpression("VendorInfo.V01, Title, Price");

Item item = table.getItem(spec);
System.out.println(item.toJSON());
```
L'output sarà simile al seguente.  

```
{"VendorInfo":{"V01":{"Name":"Acme Books","Offices":["Seattle"]}},"Price":30,"Title":"Book 210 Title"}
```

## Scrittura in batch: collocazione ed eliminazione di più elementi
<a name="BatchWriteDocumentAPIJava"></a>

La *scrittura in batch* fa riferimento alla collocazione e all'eliminazione di più item in un batch. Il metodo `batchWriteItem` ti consente di inserire ed eliminare più item da una o più tabelle con un'unica chiamata. Di seguito sono riportati i passaggi per inserire o eliminare più elementi utilizzando l'API AWS SDK per Java Document.

1. Creare un'istanza della classe `DynamoDB`.

1. Crea un'istanza della classe `TableWriteItems` che descrive tutte le operazioni di inserimento ed eliminazione per una tabella. Se vuoi scrivere su più tabelle in una sola operazione di scrittura in batch, devi creare un'istanza di `TableWriteItems` per tabella.

1. Chiama il metodo `batchWriteItem` fornendo gli oggetti `TableWriteItems` creati nella fase precedente. 

1. Elabora la risposta. Dovresti controllare se erano presenti item di richiesta non elaborati restituiti nella risposta. Questo potrebbe accadere se raggiungi la quota di throughput assegnata o si verifica un altro errore transitorio. Inoltre, DynamoDB limita la dimensione della richiesta e il numero di operazioni che possono essere specificate in una richiesta. Se si superano questi limiti, DynamoDB rifiuta la richiesta. Per ulteriori informazioni, consulta [Quote in Amazon DynamoDB](ServiceQuotas.md). 

Il seguente esempio di codice Java mostra le fasi precedenti. L'esempio esegue un'operazione `batchWriteItem` su due tabelle: `Forum` e `Thread`. Gli oggetti `TableWriteItems` corrispondenti definiscono le operazioni seguenti:
+ inserimento di un item nella tabella `Forum`.
+ Inserimento ed eliminazione di un item nella tabella `Thread`.

Il codice quindi chiama `batchWriteItem` per eseguire l'operazione.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

TableWriteItems forumTableWriteItems = new TableWriteItems("Forum")
    .withItemsToPut(
        new Item()
            .withPrimaryKey("Name", "Amazon RDS")
            .withNumber("Threads", 0));

TableWriteItems threadTableWriteItems = new TableWriteItems("Thread")
    .withItemsToPut(
        new Item()
            .withPrimaryKey("ForumName","Amazon RDS","Subject","Amazon RDS Thread 1")
    .withHashAndRangeKeysToDelete("ForumName","Some partition key value", "Amazon S3", "Some sort key value");

BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems);

// Code for checking unprocessed items is omitted in this example
```

Per un esempio di utilizzo, consulta [Esempio: operazione di scrittura in batch utilizzando l'API del AWS SDK per Java documento](batch-operation-document-api-java.md#JavaDocumentAPIBatchWrite). 

## Ricezione in batch: ricezione di più elementi
<a name="JavaDocumentAPIBatchGetItem"></a>

Il metodo `batchGetItem` ti consente di recuperare più item da una o più tabelle. Per recuperare un singolo item puoi usare il metodo `getItem`. 

Completare la procedura riportata di seguito. 

1. Creare un'istanza della classe `DynamoDB`.

1. Crea un'istanza della classe `TableKeysAndAttributes` e descrivi un elenco di valori delle chiavi primarie da recuperare da una tabella. Se vuoi leggere da più tabelle in una sola operazione Get in batch, devi creare un'istanza di `TableKeysAndAttributes` per tabella.

1. Chiama il metodo `batchGetItem` fornendo gli oggetti `TableKeysAndAttributes` creati nella fase precedente.

Il seguente esempio di codice Java mostra le fasi precedenti. L'esempio consente di recuperare due item dalla tabella `Forum` e tre item dalla tabella `Thread`.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

    TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName);
    forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName);
threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject",
    "Amazon DynamoDB","DynamoDB Thread 1",
    "Amazon DynamoDB","DynamoDB Thread 2",
    "Amazon S3","S3 Thread 1");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(
    forumTableKeysAndAttributes, threadTableKeysAndAttributes);

for (String tableName : outcome.getTableItems().keySet()) {
    System.out.println("Items in table " + tableName);
    List<Item> items = outcome.getTableItems().get(tableName);
    for (Item item : items) {
        System.out.println(item);
    }
}
```

### Specifica dei parametri facoltativi
<a name="BatchGetItemJavaDocumentAPIOptions"></a>

Insieme ai parametri richiesti, puoi anche specificare parametri opzionali usando `batchGetItem`. Puoi ad esempio fornire un `ProjectionExpression` con ogni `TableKeysAndAttributes` che definisci. Ciò ti consente di specificare gli attributi che vuoi recuperare dalla tabella.

L'esempio di codice seguente recupera due item dalla tabella `Forum`. Il parametro `withProjectionExpression` specifica che deve essere recuperato solo l'attributo `Threads`.

**Example**  

```
TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes("Forum")
    .withProjectionExpression("Threads");

forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes);
```

## Aggiornamento di un elemento
<a name="JavaDocumentAPIItemUpdate"></a>

Il metodo `updateItem` di un oggetto `Table` può aggiornare i valori degli attributi esistenti, aggiungere nuovi attributi o eliminare attributi da un item esistente. 

Il metodo `updateItem` si comporta nel modo seguente:
+ Se un item non esiste (nessun item nella tabella con la chiave primaria specificata), `updateItem` aggiunge un nuovo item alla tabella.
+ Se un item esiste, `updateItem` esegue l'aggiornamento come specificato dal parametro `UpdateExpression`.

**Nota**  
È anche possibile "aggiornare" un item usando `putItem`. Ad esempio, se chiami `putItem` per aggiungere un item alla tabella ma esiste già un item con la chiave primaria specificata, `putItem` sostituisce l'intero item. Se nell'item esistente sono presenti attributi che non sono specificati nell'input, `putItem` rimuove quegli attributi dall'item.  
Come regola generale, ti consigliamo di usare `updateItem` ogni volta che desideri modificare qualsiasi attributo dell'item. Il metodo `updateItem` modifica solo gli attributi specificati nell'input e gli altri attributi dell'item rimangono invariati.

Completare la procedura riportata di seguito. 

1. Crea un'istanza della classe `Table` per rappresentare la tabella da utilizzare.

1. Chiama il metodo `updateTable` dell'istanza di `Table`. Dovrai specificare la chiave primaria dell'item che vuoi recuperare, insieme a una `UpdateExpression` che descrive gli attributi da modificare e come modificarli.

Il seguente esempio di codice Java mostra le attività precedenti. Il codice aggiorna un item libro nella tabella `ProductCatalog`. Aggiunge un nuovo autore al set di `Authors` ed elimina l'attributo `ISBN` esistente. Inoltre, riduce il prezzo di una unità.

Una mappa `ExpressionAttributeValues` viene usata in `UpdateExpression`. I segnaposto `:val1` e `:val2` vengono sostituiti al runtime con i valori effettivi per `Authors` e `Price`.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#A", "Authors");
expressionAttributeNames.put("#P", "Price");
expressionAttributeNames.put("#I", "ISBN");

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1",
    new HashSet<String>(Arrays.asList("Author YY","Author ZZ")));
expressionAttributeValues.put(":val2", 1);   //Price

UpdateItemOutcome outcome =  table.updateItem(
    "Id",          // key attribute name
    101,           // key attribute value
    "add #A :val1 set #P = #P - :val2 remove #I", // UpdateExpression
    expressionAttributeNames,
    expressionAttributeValues);
```

### Specifica dei parametri facoltativi
<a name="UpdateItemJavaDocumentAPIOptions"></a>

Insieme ai parametri obbligatori puoi specificare anche dei parametri facoltativi per il metodo `updateItem`, inclusa una condizione che deve essere soddisfatta affinché l'aggiornamento possa avere luogo. Se la condizione specificata non è soddisfatta, AWS SDK per Java genera un`ConditionalCheckFailedException`. Ad esempio, il seguente esempio di codice Java aggiorna in base a condizioni il prezzo di un libro a 25. Specifica una `ConditionExpression` che afferma che il prezzo deve essere aggiornato solo se il prezzo esistente è 20.

**Example**  

```
Table table = dynamoDB.getTable("ProductCatalog");

Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#P", "Price");

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1", 25);  // update Price to 25...
expressionAttributeValues.put(":val2", 20);  //...but only if existing Price is 20

UpdateItemOutcome outcome = table.updateItem(
    new PrimaryKey("Id",101),
    "set #P = :val1", // UpdateExpression
    "#P = :val2",     // ConditionExpression
    expressionAttributeNames,
    expressionAttributeValues);
```

### Contatore atomico
<a name="AtomicCounterJavaDocumentAPI"></a>

Puoi usare il metodo `updateItem` per implementare un contatore atomico e incrementare o decrementare il valore di un attributo esistente senza interferire con altre richieste di scrittura. Per incrementare un contatore atomico, usa un `UpdateExpression` con un'operazione `set` per aggiungere un valore numerico a un attributo esistente di tipo `Number`.

Il seguente esempio ne dimostra l'uso, incrementando l'attributo `Quantity` di uno. Dimostra anche l'uso del parametro `ExpressionAttributeNames` in una `UpdateExpression`.

```
Table table = dynamoDB.getTable("ProductCatalog");

Map<String,String> expressionAttributeNames = new HashMap<String,String>();
expressionAttributeNames.put("#p", "PageCount");

Map<String,Object> expressionAttributeValues = new HashMap<String,Object>();
expressionAttributeValues.put(":val", 1);

UpdateItemOutcome outcome = table.updateItem(
    "Id", 121,
    "set #p = #p + :val",
    expressionAttributeNames,
    expressionAttributeValues);
```

## Eliminazione di un elemento
<a name="DeleteMidLevelJava"></a>

Il metodo `deleteItem` elimina un item da una tabella. È necessario fornire la chiave primaria dell'item che intendi eliminare.

Completare la procedura riportata di seguito. 

1. Crea un'istanza del client `DynamoDB`.

1. Chiama il metodo `deleteItem` fornendo la chiave dell'item che desideri eliminare. 

Il seguente esempio Java mostra queste attività.

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

DeleteItemOutcome outcome = table.deleteItem("Id", 101);
```

### Specifica dei parametri facoltativi
<a name="DeleteItemJavaDocumentAPIOptions"></a>

Puoi specificare i parametri facoltativi per `deleteItem`. Ad esempio, il seguente esempio di codice Java specifica una `ConditionExpression`, in cui si afferma che un item libro in `InPublication` può essere eliminato solo se il libro non è più in pubblicazione (l'attributo `ProductCatalog` è false).

**Example**  

```
Map<String,Object> expressionAttributeValues = new HashMap<String,Object>();
expressionAttributeValues.put(":val", false);

DeleteItemOutcome outcome = table.deleteItem("Id",103,
    "InPublication = :val",
    null, // ExpressionAttributeNames - not used in this example
    expressionAttributeValues);
```

# Esempio: operazioni CRUD che utilizzano l'API del documento AWS SDK per Java
<a name="JavaDocumentAPICRUDExample"></a>

Il seguente esempio di codice illustra le operazioni CRUD su un elemento di Amazon DynamoDB. L'esempio consente di creare un item, recuperarlo, eseguire vari aggiornamenti e infine eliminare l'item.

**Nota**  
L'SDK per Java offre inoltre un modello di persistenza degli oggetti che permette di mappare le classi lato client alle tabelle DynamoDB. Questo approccio può ridurre la quantità di codice da scrivere. Per ulteriori informazioni, consulta [Java 1.x: Dinamo DBMapper](DynamoDBMapper.md).

**Nota**  
In questo esempio di codice si presuppone che i dati siano già stati caricati in DynamoDB per l'account seguendo le istruzioni riportate nella sezione [Creazione di tabelle e caricamento di dati per esempi di codice in DynamoDB](SampleData.md).  
Per step-by-step istruzioni su come eseguire l'esempio seguente, vedere[Esempi di codice Java](CodeSamples.Java.md).

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DeleteItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome;
import com.amazonaws.services.dynamodbv2.document.spec.DeleteItemSpec;
import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec;
import com.amazonaws.services.dynamodbv2.document.utils.NameMap;
import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
import com.amazonaws.services.dynamodbv2.model.ReturnValue;

public class DocumentAPIItemCRUDExample {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String tableName = "ProductCatalog";

    public static void main(String[] args) throws IOException {

        createItems();

        retrieveItem();

        // Perform various updates.
        updateMultipleAttributes();
        updateAddNewAttribute();
        updateExistingAttributeConditionally();

        // Delete the item.
        deleteItem();

    }

    private static void createItems() {

        Table table = dynamoDB.getTable(tableName);
        try {

            Item item = new Item().withPrimaryKey("Id", 120).withString("Title", "Book 120 Title")
                    .withString("ISBN", "120-1111111111")
                    .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author12", "Author22")))
                    .withNumber("Price", 20).withString("Dimensions", "8.5x11.0x.75").withNumber("PageCount", 500)
                    .withBoolean("InPublication", false).withString("ProductCategory", "Book");
            table.putItem(item);

            item = new Item().withPrimaryKey("Id", 121).withString("Title", "Book 121 Title")
                    .withString("ISBN", "121-1111111111")
                    .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author21", "Author 22")))
                    .withNumber("Price", 20).withString("Dimensions", "8.5x11.0x.75").withNumber("PageCount", 500)
                    .withBoolean("InPublication", true).withString("ProductCategory", "Book");
            table.putItem(item);

        } catch (Exception e) {
            System.err.println("Create items failed.");
            System.err.println(e.getMessage());

        }
    }

    private static void retrieveItem() {
        Table table = dynamoDB.getTable(tableName);

        try {

            Item item = table.getItem("Id", 120, "Id, ISBN, Title, Authors", null);

            System.out.println("Printing item after retrieving it....");
            System.out.println(item.toJSONPretty());

        } catch (Exception e) {
            System.err.println("GetItem failed.");
            System.err.println(e.getMessage());
        }

    }

    private static void updateAddNewAttribute() {
        Table table = dynamoDB.getTable(tableName);

        try {

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 121)
                    .withUpdateExpression("set #na = :val1").withNameMap(new NameMap().with("#na", "NewAttribute"))
                    .withValueMap(new ValueMap().withString(":val1", "Some value"))
                    .withReturnValues(ReturnValue.ALL_NEW);

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after adding new attribute...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Failed to add new attribute in " + tableName);
            System.err.println(e.getMessage());
        }
    }

    private static void updateMultipleAttributes() {

        Table table = dynamoDB.getTable(tableName);

        try {

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 120)
                    .withUpdateExpression("add #a :val1 set #na=:val2")
                    .withNameMap(new NameMap().with("#a", "Authors").with("#na", "NewAttribute"))
                    .withValueMap(
                            new ValueMap().withStringSet(":val1", "Author YY", "Author ZZ").withString(":val2",
                                    "someValue"))
                    .withReturnValues(ReturnValue.ALL_NEW);

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after multiple attribute update...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Failed to update multiple attributes in " + tableName);
            System.err.println(e.getMessage());

        }
    }

    private static void updateExistingAttributeConditionally() {

        Table table = dynamoDB.getTable(tableName);

        try {

            // Specify the desired price (25.00) and also the condition (price =
            // 20.00)

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 120)
                    .withReturnValues(ReturnValue.ALL_NEW).withUpdateExpression("set #p = :val1")
                    .withConditionExpression("#p = :val2").withNameMap(new NameMap().with("#p", "Price"))
                    .withValueMap(new ValueMap().withNumber(":val1", 25).withNumber(":val2", 20));

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after conditional update to new attribute...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Error updating item in " + tableName);
            System.err.println(e.getMessage());
        }
    }

    private static void deleteItem() {

        Table table = dynamoDB.getTable(tableName);

        try {

            DeleteItemSpec deleteItemSpec = new DeleteItemSpec().withPrimaryKey("Id", 120)
                    .withConditionExpression("#ip = :val").withNameMap(new NameMap().with("#ip", "InPublication"))
                    .withValueMap(new ValueMap().withBoolean(":val", false)).withReturnValues(ReturnValue.ALL_OLD);

            DeleteItemOutcome outcome = table.deleteItem(deleteItemSpec);

            // Check the response.
            System.out.println("Printing item that was deleted...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Error deleting item in " + tableName);
            System.err.println(e.getMessage());
        }
    }
}
```

# Esempio: operazioni Batch utilizzando l'API AWS SDK per Java dei documenti
<a name="batch-operation-document-api-java"></a>

Questa sezione fornisce esempi di operazioni di scrittura e acquisizione in batch in Amazon DynamoDB utilizzando AWS SDK per Java l'API Document.

**Nota**  
L'SDK per Java offre inoltre un modello di persistenza degli oggetti che permette di mappare le classi lato client alle tabelle DynamoDB. Questo approccio può ridurre la quantità di codice da scrivere. Per ulteriori informazioni, consulta [Java 1.x: Dinamo DBMapper](DynamoDBMapper.md).

**Topics**
+ [

## Esempio: operazione di scrittura in batch utilizzando l'API del AWS SDK per Java documento
](#JavaDocumentAPIBatchWrite)
+ [

## Esempio: operazione Batch get utilizzando l'API del AWS SDK per Java documento
](#JavaDocumentAPIBatchGet)

## Esempio: operazione di scrittura in batch utilizzando l'API del AWS SDK per Java documento
<a name="JavaDocumentAPIBatchWrite"></a>

Nel seguente esempio di codice Java viene utilizzato il metodo `batchWriteItem` per eseguire le seguenti operazioni di eliminazione e inserimento:
+ inserimento di un item nella tabella `Forum`;
+ Inserimento di un item ed eliminazione di un item dalla tabella `Thread`. 

Quando crei la tua risposta di scrittura in batch, puoi specificare qualsiasi quantità di richieste di inserimento ed eliminazione in una o più tabelle. Tuttavia, `batchWriteItem` limita la dimensione di una richiesta di scrittura in batch e il numero di operazioni di inserimento ed eliminazione in una singola operazione di scrittura in batch. Se la tua richiesta eccede questi limiti, essa verrà rigettata. Se la tua tabella non dispone di sufficiente throughput assegnato per soddisfare questa richiesta, gli elementi di richiesta non eseguiti vengono restituiti nella risposta. 

Il seguente esempio controlla la risposta nel caso in cui vi siano degli elementi di richiesta non eseguiti. Se sono presenti, esegue il loopback e invia nuovamente la richiesta `batchWriteItem` con gli elementi non elaborati della richiesta. Seguendo gli esempi presenti in questa guida dovrebbe essere già avvenuta la creazione delle tabelle `Forum` e `Thread`. Puoi anche creare queste tabelle e caricare i dati di esempio a livello di programmazione. Per ulteriori informazioni, consulta [Creazione di tabelle di esempio e caricamento di dati utilizzando AWS SDK per Java](AppendixSampleDataCodeJava.md).

Per step-by-step istruzioni su come testare il seguente esempio, vedere[Esempi di codice Java](CodeSamples.Java.md). 

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.BatchWriteItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.TableWriteItems;
import com.amazonaws.services.dynamodbv2.model.WriteRequest;

public class DocumentAPIBatchWrite {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String forumTableName = "Forum";
    static String threadTableName = "Thread";

    public static void main(String[] args) throws IOException {

        writeMultipleItemsBatchWrite();

    }

    private static void writeMultipleItemsBatchWrite() {
        try {

            // Add a new item to Forum
            TableWriteItems forumTableWriteItems = new TableWriteItems(forumTableName) // Forum
                    .withItemsToPut(new Item().withPrimaryKey("Name", "Amazon RDS").withNumber("Threads", 0));

            // Add a new item, and delete an existing item, from Thread
            // This table has a partition key and range key, so need to specify
            // both of them
            TableWriteItems threadTableWriteItems = new TableWriteItems(threadTableName)
                    .withItemsToPut(
                            new Item().withPrimaryKey("ForumName", "Amazon RDS", "Subject", "Amazon RDS Thread 1")
                                    .withString("Message", "ElastiCache Thread 1 message")
                                    .withStringSet("Tags", new HashSet<String>(Arrays.asList("cache", "in-memory"))))
                    .withHashAndRangeKeysToDelete("ForumName", "Subject", "Amazon S3", "S3 Thread 100");

            System.out.println("Making the request.");
            BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems);

            do {

                // Check for unprocessed keys which could happen if you exceed
                // provisioned throughput

                Map<String, List<WriteRequest>> unprocessedItems = outcome.getUnprocessedItems();

                if (outcome.getUnprocessedItems().size() == 0) {
                    System.out.println("No unprocessed items found");
                } else {
                    System.out.println("Retrieving the unprocessed items");
                    outcome = dynamoDB.batchWriteItemUnprocessed(unprocessedItems);
                }

            } while (outcome.getUnprocessedItems().size() > 0);

        } catch (Exception e) {
            System.err.println("Failed to retrieve items: ");
            e.printStackTrace(System.err);
        }

    }

}
```

## Esempio: operazione Batch get utilizzando l'API del AWS SDK per Java documento
<a name="JavaDocumentAPIBatchGet"></a>

Nel seguente esempio di codice Java si utilizza il metodo `batchGetItem` per recuperare più item dalle tabelle `Forum` e `Thread`. L'item `BatchGetItemRequest` specifica i nomi delle tabelle e un elenco di chiavi per ogni item da ottenere. Nell'esempio si esegue la risposta stampando gli elementi recuperati.

**Nota**  
In questo esempio di codice si presuppone che i dati siano già stati caricati in DynamoDB per l'account seguendo le istruzioni riportate nella sezione [Creazione di tabelle e caricamento di dati per esempi di codice in DynamoDB](SampleData.md).  
Per step-by-step istruzioni su come eseguire l'esempio seguente, consulta[Esempi di codice Java](CodeSamples.Java.md).

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.BatchGetItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.TableKeysAndAttributes;
import com.amazonaws.services.dynamodbv2.model.KeysAndAttributes;

public class DocumentAPIBatchGet {
    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String forumTableName = "Forum";
    static String threadTableName = "Thread";

    public static void main(String[] args) throws IOException {
        retrieveMultipleItemsBatchGet();
    }

    private static void retrieveMultipleItemsBatchGet() {

        try {

            TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName);
            // Add a partition key
            forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB");

            TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName);
            // Add a partition key and a sort key
            threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject", "Amazon DynamoDB",
                    "DynamoDB Thread 1", "Amazon DynamoDB", "DynamoDB Thread 2", "Amazon S3", "S3 Thread 1");

            System.out.println("Making the request.");

            BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes,
                    threadTableKeysAndAttributes);

            Map<String, KeysAndAttributes> unprocessed = null;

            do {
                for (String tableName : outcome.getTableItems().keySet()) {
                    System.out.println("Items in table " + tableName);
                    List<Item> items = outcome.getTableItems().get(tableName);
                    for (Item item : items) {
                        System.out.println(item.toJSONPretty());
                    }
                }

                // Check for unprocessed keys which could happen if you exceed
                // provisioned
                // throughput or reach the limit on response size.
                unprocessed = outcome.getUnprocessedKeys();

                if (unprocessed.isEmpty()) {
                    System.out.println("No unprocessed keys found");
                } else {
                    System.out.println("Retrieving the unprocessed keys");
                    outcome = dynamoDB.batchGetItemUnprocessed(unprocessed);
                }

            } while (!unprocessed.isEmpty());

        } catch (Exception e) {
            System.err.println("Failed to retrieve items.");
            System.err.println(e.getMessage());
        }

    }

}
```

# Esempio: gestione degli attributi di tipo binario utilizzando l'API del AWS SDK per Java documento
<a name="JavaDocumentAPIBinaryTypeExample"></a>

Il seguente esempio di codice Java illustra come gestire gli attributi di tipo binario. L'esempio aggiunge un item alla tabella `Reply`. L'item include un attributo di tipo binario (`ExtendedMessage`) che memorizza i dati compressi. L'esempio recupera quindi l'item e stampa tutti valori degli attributi. Nell'esempio si utilizza la classe `GZIPOutputStream` per comprimere un flusso di esempio e assegnarlo all'attributo `ExtendedMessage`. Quando l'attributo binario viene recuperato, viene decompresso utilizzando la classe `GZIPInputStream`. 

**Nota**  
L'SDK per Java offre inoltre un modello di persistenza degli oggetti che permette di mappare le classi lato client alle tabelle DynamoDB. Questo approccio può ridurre la quantità di codice da scrivere. Per ulteriori informazioni, consulta [Java 1.x: Dinamo DBMapper](DynamoDBMapper.md).

Se hai seguito la sezione [Creazione di tabelle e caricamento di dati per esempi di codice in DynamoDB](SampleData.md) dovresti aver già creato la tabella `Reply`. Puoi anche creare questa tabella a livello di programmazione. Per ulteriori informazioni, consulta [Creazione di tabelle di esempio e caricamento di dati utilizzando AWS SDK per Java](AppendixSampleDataCodeJava.md).

Per step-by-step istruzioni su come testare il seguente esempio, vedere[Esempi di codice Java](CodeSamples.Java.md). 

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.spec.GetItemSpec;

public class DocumentAPIItemBinaryExample {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String tableName = "Reply";
    static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    public static void main(String[] args) throws IOException {
        try {

            // Format the primary key values
            String threadId = "Amazon DynamoDB#DynamoDB Thread 2";

            dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
            String replyDateTime = dateFormatter.format(new Date());

            // Add a new reply with a binary attribute type
            createItem(threadId, replyDateTime);

            // Retrieve the reply with a binary attribute type
            retrieveItem(threadId, replyDateTime);

            // clean up by deleting the item
            deleteItem(threadId, replyDateTime);
        } catch (Exception e) {
            System.err.println("Error running the binary attribute type example: " + e);
            e.printStackTrace(System.err);
        }
    }

    public static void createItem(String threadId, String replyDateTime) throws IOException {

        Table table = dynamoDB.getTable(tableName);

        // Craft a long message
        String messageInput = "Long message to be compressed in a lengthy forum reply";

        // Compress the long message
        ByteBuffer compressedMessage = compressString(messageInput.toString());

        table.putItem(new Item().withPrimaryKey("Id", threadId).withString("ReplyDateTime", replyDateTime)
                .withString("Message", "Long message follows").withBinary("ExtendedMessage", compressedMessage)
                .withString("PostedBy", "User A"));
    }

    public static void retrieveItem(String threadId, String replyDateTime) throws IOException {

        Table table = dynamoDB.getTable(tableName);

        GetItemSpec spec = new GetItemSpec().withPrimaryKey("Id", threadId, "ReplyDateTime", replyDateTime)
                .withConsistentRead(true);

        Item item = table.getItem(spec);

        // Uncompress the reply message and print
        String uncompressed = uncompressString(ByteBuffer.wrap(item.getBinary("ExtendedMessage")));

        System.out.println("Reply message:\n" + " Id: " + item.getString("Id") + "\n" + " ReplyDateTime: "
                + item.getString("ReplyDateTime") + "\n" + " PostedBy: " + item.getString("PostedBy") + "\n"
                + " Message: "
                + item.getString("Message") + "\n" + " ExtendedMessage (uncompressed): " + uncompressed + "\n");
    }

    public static void deleteItem(String threadId, String replyDateTime) {

        Table table = dynamoDB.getTable(tableName);
        table.deleteItem("Id", threadId, "ReplyDateTime", replyDateTime);
    }

    private static ByteBuffer compressString(String input) throws IOException {
        // Compress the UTF-8 encoded String into a byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream os = new GZIPOutputStream(baos);
        os.write(input.getBytes("UTF-8"));
        os.close();
        baos.close();
        byte[] compressedBytes = baos.toByteArray();

        // The following code writes the compressed bytes to a ByteBuffer.
        // A simpler way to do this is by simply calling
        // ByteBuffer.wrap(compressedBytes);
        // However, the longer form below shows the importance of resetting the
        // position of the buffer
        // back to the beginning of the buffer if you are writing bytes directly
        // to it, since the SDK
        // will consider only the bytes after the current position when sending
        // data to DynamoDB.
        // Using the "wrap" method automatically resets the position to zero.
        ByteBuffer buffer = ByteBuffer.allocate(compressedBytes.length);
        buffer.put(compressedBytes, 0, compressedBytes.length);
        buffer.position(0); // Important: reset the position of the ByteBuffer
                            // to the beginning
        return buffer;
    }

    private static String uncompressString(ByteBuffer input) throws IOException {
        byte[] bytes = input.array();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPInputStream is = new GZIPInputStream(bais);

        int chunkSize = 1024;
        byte[] buffer = new byte[chunkSize];
        int length = 0;
        while ((length = is.read(buffer, 0, chunkSize)) != -1) {
            baos.write(buffer, 0, length);
        }

        String result = new String(baos.toByteArray(), "UTF-8");

        is.close();
        baos.close();
        bais.close();

        return result;
    }
}
```

# Uso di elementi: .NET
<a name="LowLevelDotNetItemCRUD"></a>

È possibile utilizzare l'API di AWS SDK per .NET basso livello per eseguire operazioni tipiche di creazione, lettura, aggiornamento ed eliminazione (CRUD) su un elemento di una tabella. Di seguito sono riportate le fasi comuni per eseguire le operazione CRUD sui dati, usando l'API di basso livello .NET:

1. Crea un'istanza della classe `AmazonDynamoDBClient` (client).

1. Fornisci i parametri obbligatori e specifici per l'operazione in un oggetto di richiesta corrispondente.

   Per esempio, usa l'oggetto di richiesta `PutItemRequest` durante il caricamento di un item e l'oggetto di richiesta `GetItemRequest` quando recuperi un item esistente. 

   Puoi usare l'oggetto di richiesta per fornire sia i parametri obbligatori sia quelli facoltativi; 

1. Eseguire il metodo appropriato fornito dal client inviando l'oggetto di richiesta creato nella fase precedente. 

   Il client `AmazonDynamoDBClient` fornisce i metodi `PutItem`, `GetItem`, `UpdateItem` e `DeleteItem` per le operazioni CRUD.

**Topics**
+ [

## Collocazione di un elemento
](#PutItemLowLevelAPIDotNet)
+ [

## Ottenimento di un elemento
](#GetItemLowLevelDotNET)
+ [

## Aggiornamento di un elemento
](#UpdateItemLowLevelDotNet)
+ [

## Contatore atomico
](#AtomicCounterLowLevelDotNet)
+ [

## Eliminazione di un elemento
](#DeleteMidLevelDotNet)
+ [

## Scrittura in batch: collocazione ed eliminazione di più elementi
](#BatchWriteLowLevelDotNet)
+ [

## Ricezione in batch: ricezione di più elementi
](#BatchGetLowLevelDotNet)
+ [

# Esempio: operazioni CRUD che utilizzano l'API di AWS SDK per .NET basso livello
](LowLevelDotNetItemsExample.md)
+ [

# Esempio: operazioni Batch utilizzando l'API AWS SDK per .NET di basso livello
](batch-operation-lowlevel-dotnet.md)
+ [

# Esempio: gestione degli attributi di tipo binario utilizzando l'API di AWS SDK per .NET basso livello
](LowLevelDotNetBinaryTypeExample.md)

## Collocazione di un elemento
<a name="PutItemLowLevelAPIDotNet"></a>

Il metodo `PutItem` carica un item nella tabella. Se l'item esiste, lo sostituisce per intero.

**Nota**  
Se invece di sostituire l'intero item vuoi aggiornare solo attributi specifici, puoi utilizzare il metodo `UpdateItem`. Per ulteriori informazioni, consulta [Aggiornamento di un elemento](#UpdateItemLowLevelDotNet).

Di seguito sono riportate le fasi per caricare un item usando l'API di basso livello dell'SDK per .NET:

1. Creare un'istanza della classe `AmazonDynamoDBClient`.

1. fornisci i parametri obbligatori creando un istanza della classe `PutItemRequest`.

   Per inserire un item, è necessario fornire il nome della tabella e l'item; 

1. Eseguire il metodo `PutItem` fornendo l'oggetto `PutItemRequest` creato nella fase precedente.

Il seguente esempio C\$1 mostra le fasi precedenti. L'esempio carica un item nella tabella `ProductCatalog`.

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new PutItemRequest
{
   TableName = tableName,
   Item = new Dictionary<string, AttributeValue>()
      {
          { "Id", new AttributeValue { N = "201" }},
          { "Title", new AttributeValue { S = "Book 201 Title" }},
          { "ISBN", new AttributeValue { S = "11-11-11-11" }},
          { "Price", new AttributeValue { S = "20.00" }},
          {
            "Authors",
            new AttributeValue
            { SS = new List<string>{"Author1", "Author2"}   }
          }
      }
};
client.PutItem(request);
```

Nell'esempio precedente, carica un item libro che abbia gli attributi `Id`, `Title`, `ISBN` e `Authors`. Nota che `Id` è un attributo di tipo numerico, mentre tutti gli altri sono tipo stringa. Authors è un set di `String`.

### Specifica dei parametri facoltativi
<a name="PutItemLowLevelAPIDotNetOptions"></a>

Puoi anche fornire parametri facoltativi usando l'oggetto `PutItemRequest`, come mostrato nel seguente esempio C\$1. L'esempio specifica i parametri facoltativi seguenti:
+ `ExpressionAttributeNames`, `ExpressionAttributeValues` e `ConditionExpression` specificano che l'item può essere sostituito solo se l'item esistente ha l'attributo ISBN con un valore specifico.
+ Il parametro `ReturnValues` per richiedere il vecchio item nella risposta.

**Example**  

```
var request = new PutItemRequest
 {
   TableName = tableName,
   Item = new Dictionary<string, AttributeValue>()
               {
                   { "Id", new AttributeValue { N = "104" }},
                   { "Title", new AttributeValue { S = "Book 104  Title" }},
                   { "ISBN", new AttributeValue { S = "444-4444444444" }},
                   { "Authors",
                     new AttributeValue { SS = new List<string>{"Author3"}}}
               },
    // Optional parameters.
    ExpressionAttributeNames = new Dictionary<string,string>()
    {
        {"#I", "ISBN"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":isbn",new AttributeValue {S = "444-4444444444"}}
    },
    ConditionExpression = "#I = :isbn"

};
var response = client.PutItem(request);
```

Per ulteriori informazioni, consulta [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html).

## Ottenimento di un elemento
<a name="GetItemLowLevelDotNET"></a>

Il metodo `GetItem` recupera un item.

**Nota**  
Per recuperare più item puoi usare il metodo `BatchGetItem`. Per ulteriori informazioni, consulta [Ricezione in batch: ricezione di più elementi](#BatchGetLowLevelDotNet).

Di seguito sono riportate le fasi per recuperare un item esistente usando l'API di basso livello di AWS SDK per .NET .

1. Creare un'istanza della classe `AmazonDynamoDBClient`.

1. fornisci i parametri obbligatori creando un istanza della classe `GetItemRequest`.

   Per ottenere un item, è necessario fornire il nome della tabella e la chiave primaria dell'item. 

1. Eseguire il metodo `GetItem` fornendo l'oggetto `GetItemRequest` creato nella fase precedente.

Il seguente esempio C\$1 mostra le fasi precedenti. L'esempio recupera un item dalla tabella `ProductCatalog`.

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new GetItemRequest
 {
   TableName = tableName,
   Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },
 };
 var response = client.GetItem(request);

// Check the response.
var result = response.GetItemResult;
var attributeMap = result.Item; // Attribute list in the response.
```

### Specifica dei parametri facoltativi
<a name="GetItemLowLevelDotNETOptions"></a>

Puoi anche fornire parametri facoltativi usando l'oggetto `GetItemRequest`, come mostrato nel seguente esempio C\$1. L'esempio specifica i parametri facoltativi seguenti:
+ Il parametro `ProjectionExpression` per specificare gli attributi da recuperare.
+ Il parametro `ConsistentRead` per eseguire una lettura estremamente coerente. Per ulteriori informazioni sulla lettura coerente, consulta [Coerenza di lettura di DynamoDB](HowItWorks.ReadConsistency.md).

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new GetItemRequest
 {
   TableName = tableName,
   Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },
   // Optional parameters.
   ProjectionExpression = "Id, ISBN, Title, Authors",
   ConsistentRead = true
 };

 var response = client.GetItem(request);

// Check the response.
var result = response.GetItemResult;
var attributeMap = result.Item;
```

Per ulteriori informazioni, consulta [GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html).

## Aggiornamento di un elemento
<a name="UpdateItemLowLevelDotNet"></a>

Il metodo `UpdateItem` aggiorna un item esistente se presente. Puoi usare l'operazione `UpdateItem` per aggiornare i valori degli attributi esistenti, aggiungere nuovi attributi o eliminare attributi dalla raccolta esistente. Se non viene trovato l'item che dispone della chiave primaria specificata, viene aggiunto un nuovo item.

L'operazione `UpdateItem` usa le seguenti linee guida:
+ Se l'item non esiste, `UpdateItem` aggiunge un nuovo item usando la chiave primaria specificata nell'input.
+ Se l'item esiste, `UpdateItem` applica gli aggiornamenti come segue:
  + sostituisce il valore dell'attributo esistente attraverso i valori dell'aggiornamento;
  + se l'attributo che fornisci nell'input non esiste, viene aggiunto un nuovo attributo all'item;
  + se l'attributo di input è nullo, viene eliminato l'attributo qualora presente; 
  + se utilizzi `ADD` per `Action`, puoi aggiungere valori a un set esistente (di stringhe o numeri) o aggiungere (se usi un numero positivo) o sottrarre (se usi un numero negativo) matematicamente dal valore dell'attributo numerico esistente.

**Nota**  
L'operazione `PutItem` può anche eseguire un aggiornamento. Per ulteriori informazioni, consulta [Collocazione di un elemento](#PutItemLowLevelAPIDotNet). Ad esempio, se chiami `PutItem` per caricare un item e la chiave primaria esiste, l'operazione `PutItem` sostituisce l'intero item. Se vi sono attributi nell'item esistente e quegli attributi non sono specificati nell'input, l'operazione `PutItem` li elimina. Tuttavia, `UpdateItem` aggiorna solo gli attributi di input specificati. Qualsiasi altro attributo esistente di quell'item rimarrà invariato. 

Di seguito sono riportate le fasi per aggiornare un item esistente usando l'API di basso livello dell'SDK per .NET:

1. Creare un'istanza della classe `AmazonDynamoDBClient`.

1. fornisci i parametri obbligatori creando un istanza della classe `UpdateItemRequest`.

   Questo è l'oggetto di richiesta in cui descrivi tutti gli aggiornamenti, come l'aggiunta di attributi, l'aggiornamento di quelli esistenti o l'eliminazione di attributi. Per rimuovere un attributo esistente, specifica il nome dell'attributo con valore nullo; 

1. Eseguire il metodo `UpdateItem` fornendo l'oggetto `UpdateItemRequest` creato nella fase precedente. 

Il seguente esempio di codice C\$1 mostra le fasi precedenti. L'esempio aggiorna un item libro nella tabella `ProductCatalog`. Aggiunge un nuovo autore alla raccolta `Authors` ed elimina l'attributo `ISBN` esistente. Inoltre, riduce il prezzo di una unità.



```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new UpdateItemRequest
{
    TableName = tableName,
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },
    ExpressionAttributeNames = new Dictionary<string,string>()
    {
        {"#A", "Authors"},
        {"#P", "Price"},
        {"#NA", "NewAttribute"},
        {"#I", "ISBN"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":auth",new AttributeValue { SS = {"Author YY","Author ZZ"}}},
        {":p",new AttributeValue {N = "1"}},
        {":newattr",new AttributeValue {S = "someValue"}},
    },

    // This expression does the following:
    // 1) Adds two new authors to the list
    // 2) Reduces the price
    // 3) Adds a new attribute to the item
    // 4) Removes the ISBN attribute from the item
    UpdateExpression = "ADD #A :auth SET #P = #P - :p, #NA = :newattr REMOVE #I"
};
var response = client.UpdateItem(request);
```

### Specifica dei parametri facoltativi
<a name="UpdateItemLowLevelDotNETOptions"></a>

Puoi anche fornire parametri facoltativi usando l'oggetto `UpdateItemRequest`, come mostrato nel seguente esempio C\$1. Esso specifica i seguenti parametri opzionali:
+ `ExpressionAttributeValues` e `ConditionExpression` per specificare che il prezzo può essere aggiornato solo se il prezzo esistente è 20,00;
+ il parametro `ReturnValues` per richiedere l'item aggiornato nella risposta. 

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new UpdateItemRequest
{
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },

    // Update price only if the current price is 20.00.
    ExpressionAttributeNames = new Dictionary<string,string>()
    {
        {"#P", "Price"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":newprice",new AttributeValue {N = "22"}},
        {":currprice",new AttributeValue {N = "20"}}
    },
    UpdateExpression = "SET #P = :newprice",
    ConditionExpression = "#P = :currprice",
    TableName = tableName,
    ReturnValues = "ALL_NEW" // Return all the attributes of the updated item.
};

var response = client.UpdateItem(request);
```

Per ulteriori informazioni, consulta [UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html). 

## Contatore atomico
<a name="AtomicCounterLowLevelDotNet"></a>

Puoi usare il metodo `updateItem` per implementare un contatore atomico e incrementare o decrementare il valore di un attributo esistente senza interferire con altre richieste di scrittura. Per aggiornare un contatore atomico, usa `updateItem` con un attributo di tipo `Number` nel parametro `UpdateExpression` e `ADD` come `Action`.

Il seguente esempio ne dimostra l'uso, incrementando l'attributo `Quantity` di uno.

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new UpdateItemRequest
{
    Key = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = "121" } } },
    ExpressionAttributeNames = new Dictionary<string, string>()
    {
        {"#Q", "Quantity"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":incr",new AttributeValue {N = "1"}}
    },
    UpdateExpression = "SET #Q = #Q + :incr",
    TableName = tableName
};

var response = client.UpdateItem(request);
```

## Eliminazione di un elemento
<a name="DeleteMidLevelDotNet"></a>

Il metodo `DeleteItem` elimina un item da una tabella. 

Di seguito sono riportate le fasi per eliminare un item usando l'API dell'SDK per .NET di basso livello. 

1. Creare un'istanza della classe `AmazonDynamoDBClient`.

1. fornisci i parametri obbligatori creando un istanza della classe `DeleteItemRequest`.

    Per eliminare un item, sono necessari il nome della tabella e la chiave primaria dell'item; 

1. Eseguire il metodo `DeleteItem` fornendo l'oggetto `DeleteItemRequest` creato nella fase precedente. 

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new DeleteItemRequest
{
    TableName = tableName,
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "201" } } },
};

var response = client.DeleteItem(request);
```

### Specifica dei parametri facoltativi
<a name="DeleteItemLowLevelDotNETOptions"></a>

Puoi anche fornire parametri facoltativi usando l'oggetto `DeleteItemRequest`, come mostrato nel seguente esempio di codice C\$1. Esso specifica i seguenti parametri opzionali:
+ `ExpressionAttributeValues`e `ConditionExpression` per specificare che l'elemento del libro può essere eliminato solo se non è più in pubblicazione (il valore dell' InPublication attributo è false). 
+ il parametro `ReturnValues` per richiedere l'item eliminato nella risposta.

**Example**  

```
var request = new DeleteItemRequest
{
    TableName = tableName,
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "201" } } },

    // Optional parameters.
    ReturnValues = "ALL_OLD",
    ExpressionAttributeNames = new Dictionary<string, string>()
    {
        {"#IP", "InPublication"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":inpub",new AttributeValue {BOOL = false}}
    },
    ConditionExpression = "#IP = :inpub"
};

var response = client.DeleteItem(request);
```

Per ulteriori informazioni, consulta [DeleteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html).

## Scrittura in batch: collocazione ed eliminazione di più elementi
<a name="BatchWriteLowLevelDotNet"></a>

La *scrittura in batch* fa riferimento alla collocazione e all'eliminazione di più item in un batch. Il metodo `BatchWriteItem` ti consente di inserire ed eliminare più item da una o più tabelle con un'unica chiamata. Di seguito sono riportate le fasi per recuperare più item usando l'API di basso livello dell'SDK per .NET.

1. Creare un'istanza della classe `AmazonDynamoDBClient`.

1. descrivi tutte le operazioni di inserimento ed eliminazione creando un istanza della classe `BatchWriteItemRequest`;

1. Eseguire il metodo `BatchWriteItem` fornendo l'oggetto `BatchWriteItemRequest` creato nella fase precedente.

1. Elabora la risposta. Dovresti controllare se erano presenti item di richiesta non elaborati restituiti nella risposta. Questo potrebbe accadere se raggiungi la quota di throughput assegnata o si verifica un altro errore transitorio. Inoltre, DynamoDB limita la dimensione della richiesta e il numero di operazioni che possono essere specificate in una richiesta. Se si superano questi limiti, DynamoDB rifiuta la richiesta. Per ulteriori informazioni, consulta [BatchWriteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html). 

Il seguente esempio di codice C\$1 mostra le fasi precedenti. L'esempio crea un `BatchWriteItemRequest` per eseguire le seguenti operazioni di scrittura:
+ inserisci un item nella tabella `Forum`;
+ inserisce ed elimina un item dalla tabella `Thread`.

Il codice quindi esegue `BatchWriteItem` per l'operazione in batch.

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();

string table1Name = "Forum";
string table2Name = "Thread";

var request = new BatchWriteItemRequest
 {
   RequestItems = new Dictionary<string, List<WriteRequest>>
    {
      {
        table1Name, new List<WriteRequest>
        {
          new WriteRequest
          {
             PutRequest = new PutRequest
             {
                Item = new Dictionary<string,AttributeValue>
                {
                  { "Name", new AttributeValue { S = "Amazon S3 forum" } },
                  { "Threads", new AttributeValue { N = "0" }}
                }
             }
          }
        }
      } ,
      {
        table2Name, new List<WriteRequest>
        {
          new WriteRequest
          {
            PutRequest = new PutRequest
            {
               Item = new Dictionary<string,AttributeValue>
               {
                 { "ForumName", new AttributeValue { S = "Amazon S3 forum" } },
                 { "Subject", new AttributeValue { S = "My sample question" } },
                 { "Message", new AttributeValue { S = "Message Text." } },
                 { "KeywordTags", new AttributeValue { SS = new List<string> { "Amazon S3", "Bucket" }  } }
               }
            }
          },
          new WriteRequest
          {
             DeleteRequest = new DeleteRequest
             {
                Key = new Dictionary<string,AttributeValue>()
                {
                   { "ForumName", new AttributeValue { S = "Some forum name" } },
                   { "Subject", new AttributeValue { S = "Some subject" } }
                }
             }
          }
        }
      }
    }
 };
response = client.BatchWriteItem(request);
```

Per un esempio di utilizzo, consulta [Esempio: operazioni Batch utilizzando l'API AWS SDK per .NET di basso livello](batch-operation-lowlevel-dotnet.md). 

## Ricezione in batch: ricezione di più elementi
<a name="BatchGetLowLevelDotNet"></a>

Il metodo `BatchGetItem` ti consente di recuperare più item da una o più tabelle. 

**Nota**  
Per recuperare un singolo item puoi usare il metodo `GetItem`. 

Di seguito sono riportate le fasi per recuperare più item usando l'API di basso livello di AWS SDK per .NET .

1. Creare un'istanza della classe `AmazonDynamoDBClient`.

1. fornisci i parametri obbligatori creando un istanza della classe `BatchGetItemRequest`.

   Per recuperare più item, sono necessari il nome della tabella e un elenco dei valori della chiave primaria. 

1. Eseguire il metodo `BatchGetItem` fornendo l'oggetto `BatchGetItemRequest` creato nella fase precedente.

1. Elabora la risposta. Dovresti controllare se erano presenti chiavi non elaborate. Questo potrebbe accadere se hai raggiunto la quota di throughput assegnata o alcuni errori di transizione.

Il seguente esempio di codice C\$1 mostra le fasi precedenti. L'esempio recupera gli elementi da due tabelle, `Forum` e `Thread`. La richiesta specifica due item nella tabella `Forum` e tre nella tabella `Thread`. La risposta include item da entrambe le tabelle. Il codice mostra come puoi elaborare la risposta.



```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();

string table1Name = "Forum";
string table2Name = "Thread";

var request = new BatchGetItemRequest
{
  RequestItems = new Dictionary<string, KeysAndAttributes>()
  {
    { table1Name,
      new KeysAndAttributes
      {
        Keys = new List<Dictionary<string, AttributeValue>>()
        {
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "DynamoDB" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "Amazon S3" } }
          }
        }
      }
    },
    {
      table2Name,
      new KeysAndAttributes
      {
        Keys = new List<Dictionary<string, AttributeValue>>()
        {
          new Dictionary<string, AttributeValue>()
          {
            { "ForumName", new AttributeValue { S = "DynamoDB" } },
            { "Subject", new AttributeValue { S = "DynamoDB Thread 1" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "ForumName", new AttributeValue { S = "DynamoDB" } },
            { "Subject", new AttributeValue { S = "DynamoDB Thread 2" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "ForumName", new AttributeValue { S = "Amazon S3" } },
            { "Subject", new AttributeValue { S = "Amazon S3 Thread 1" } }
          }
        }
      }
    }
  }
};

var response = client.BatchGetItem(request);

// Check the response.
var result = response.BatchGetItemResult;
var responses = result.Responses; // The attribute list in the response.

var table1Results = responses[table1Name];
Console.WriteLine("Items in table {0}" + table1Name);
foreach (var item1 in table1Results.Items)
{
  PrintItem(item1);
}

var table2Results = responses[table2Name];
Console.WriteLine("Items in table {1}" + table2Name);
foreach (var item2 in table2Results.Items)
{
  PrintItem(item2);
}
// Any unprocessed keys? could happen if you exceed ProvisionedThroughput or some other error.
Dictionary<string, KeysAndAttributes> unprocessedKeys = result.UnprocessedKeys;
foreach (KeyValuePair<string, KeysAndAttributes> pair in unprocessedKeys)
{
    Console.WriteLine(pair.Key, pair.Value);
}
```



### Specifica dei parametri facoltativi
<a name="BatchGetItemLowLevelDotNETOptions"></a>

Puoi anche fornire parametri facoltativi usando l'oggetto `BatchGetItemRequest`, come mostrato nel seguente esempio di codice C\$1. L'esempio recupera un item dalla tabella `Forum`. Esso specifica il seguente parametro opzionale:
+  Il parametro `ProjectionExpression` per specificare gli attributi da recuperare.

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();

string table1Name = "Forum";

var request = new BatchGetItemRequest
{
  RequestItems = new Dictionary<string, KeysAndAttributes>()
  {
    { table1Name,
      new KeysAndAttributes
      {
        Keys = new List<Dictionary<string, AttributeValue>>()
        {
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "DynamoDB" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "Amazon S3" } }
          }
        }
      },
      // Optional - name of an attribute to retrieve.
      ProjectionExpression = "Title"
    }
  }
};

var response = client.BatchGetItem(request);
```

Per ulteriori informazioni, consulta [BatchGetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html). 

# Esempio: operazioni CRUD che utilizzano l'API di AWS SDK per .NET basso livello
<a name="LowLevelDotNetItemsExample"></a>

Il seguente esempio di codice C\$1 illustra le operazioni CRUD su un elemento di Amazon DynamoDB. L'esempio consente di aggiungere un item alla tabella `ProductCatalog`, di recuperarlo, eseguire diversi aggiornamenti e, infine, eliminare l'item. Se questa tabella non è stata creata, è possibile crearla anche tramite programmazione. Per ulteriori informazioni, consulta [Creazione di tabelle di esempio e caricamento di dati utilizzando AWS SDK per .NET](AppendixSampleDataCodeDotNET.md).

Per step-by-step istruzioni su come testare il seguente esempio, vedere. [Esempi di codice .NET](CodeSamples.DotNet.md) 

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;
using Amazon.SecurityToken;

namespace com.amazonaws.codesamples
{
    class LowLevelItemCRUDExample
    {
        private static string tableName = "ProductCatalog";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                CreateItem();
                RetrieveItem();

                // Perform various updates.
                UpdateMultipleAttributes();
                UpdateExistingAttributeConditionally();

                // Delete item.
                DeleteItem();
                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
        }

        private static void CreateItem()
        {
            var request = new PutItemRequest
            {
                TableName = tableName,
                Item = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  }},
                { "Title", new AttributeValue {
                      S = "Book 201 Title"
                  }},
                { "ISBN", new AttributeValue {
                      S = "11-11-11-11"
                  }},
                { "Authors", new AttributeValue {
                      SS = new List<string>{"Author1", "Author2" }
                  }},
                { "Price", new AttributeValue {
                      N = "20.00"
                  }},
                { "Dimensions", new AttributeValue {
                      S = "8.5x11.0x.75"
                  }},
                { "InPublication", new AttributeValue {
                      BOOL = false
                  } }
            }
            };
            client.PutItem(request);
        }

        private static void RetrieveItem()
        {
            var request = new GetItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },
                ProjectionExpression = "Id, ISBN, Title, Authors",
                ConsistentRead = true
            };
            var response = client.GetItem(request);

            // Check the response.
            var attributeList = response.Item; // attribute list in the response.
            Console.WriteLine("\nPrinting item after retrieving it ............");
            PrintItem(attributeList);
        }

        private static void UpdateMultipleAttributes()
        {
            var request = new UpdateItemRequest
            {
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },
                // Perform the following updates:
                // 1) Add two new authors to the list
                // 1) Set a new attribute
                // 2) Remove the ISBN attribute
                ExpressionAttributeNames = new Dictionary<string, string>()
            {
                {"#A","Authors"},
                {"#NA","NewAttribute"},
                {"#I","ISBN"}
            },
                ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
            {
                {":auth",new AttributeValue {
                     SS = {"Author YY", "Author ZZ"}
                 }},
                {":new",new AttributeValue {
                     S = "New Value"
                 }}
            },

                UpdateExpression = "ADD #A :auth SET #NA = :new REMOVE #I",

                TableName = tableName,
                ReturnValues = "ALL_NEW" // Give me all attributes of the updated item.
            };
            var response = client.UpdateItem(request);

            // Check the response.
            var attributeList = response.Attributes; // attribute list in the response.
                                                     // print attributeList.
            Console.WriteLine("\nPrinting item after multiple attribute update ............");
            PrintItem(attributeList);
        }

        private static void UpdateExistingAttributeConditionally()
        {
            var request = new UpdateItemRequest
            {
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },
                ExpressionAttributeNames = new Dictionary<string, string>()
            {
                {"#P", "Price"}
            },
                ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
            {
                {":newprice",new AttributeValue {
                     N = "22.00"
                 }},
                {":currprice",new AttributeValue {
                     N = "20.00"
                 }}
            },
                // This updates price only if current price is 20.00.
                UpdateExpression = "SET #P = :newprice",
                ConditionExpression = "#P = :currprice",

                TableName = tableName,
                ReturnValues = "ALL_NEW" // Give me all attributes of the updated item.
            };
            var response = client.UpdateItem(request);

            // Check the response.
            var attributeList = response.Attributes; // attribute list in the response.
            Console.WriteLine("\nPrinting item after updating price value conditionally ............");
            PrintItem(attributeList);
        }

        private static void DeleteItem()
        {
            var request = new DeleteItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },

                // Return the entire item as it appeared before the update.
                ReturnValues = "ALL_OLD",
                ExpressionAttributeNames = new Dictionary<string, string>()
            {
                {"#IP", "InPublication"}
            },
                ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
            {
                {":inpub",new AttributeValue {
                     BOOL = false
                 }}
            },
                ConditionExpression = "#IP = :inpub"
            };

            var response = client.DeleteItem(request);

            // Check the response.
            var attributeList = response.Attributes; // Attribute list in the response.
                                                     // Print item.
            Console.WriteLine("\nPrinting item that was just deleted ............");
            PrintItem(attributeList);
        }

        private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
        {
            foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
            {
                string attributeName = kvp.Key;
                AttributeValue value = kvp.Value;

                Console.WriteLine(
                    attributeName + " " +
                    (value.S == null ? "" : "S=[" + value.S + "]") +
                    (value.N == null ? "" : "N=[" + value.N + "]") +
                    (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
                    (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]")
                    );
            }
            Console.WriteLine("************************************************");
        }
    }
}
```

# Esempio: operazioni Batch utilizzando l'API AWS SDK per .NET di basso livello
<a name="batch-operation-lowlevel-dotnet"></a>

**Topics**
+ [

## Esempio: operazione di scrittura in batch utilizzando l'API AWS SDK per .NET di basso livello
](#batch-write-low-level-dotnet)
+ [

## Esempio: operazione Batch get utilizzando l'API di AWS SDK per .NET basso livello
](#LowLevelDotNetBatchGet)

In questa sezione vengono forniti esempi di operazioni in batch, *scrittura in batch* e *get in batch* supportate da Amazon DynamoDB.

## Esempio: operazione di scrittura in batch utilizzando l'API AWS SDK per .NET di basso livello
<a name="batch-write-low-level-dotnet"></a>

Nel seguente esempio di codice C\$1 viene utilizzato il metodo `BatchWriteItem` per eseguire le seguenti operazioni di eliminazione e inserimento:
+ inserimento di un item nella tabella `Forum`;
+ Inserimento di un item ed eliminazione di un item dalla tabella `Thread`. 

Quando crei la tua risposta di scrittura in batch, puoi specificare qualsiasi quantità di richieste di inserimento ed eliminazione in una o più tabelle. Tuttavia, `BatchWriteItem` limita la dimensione di una richiesta di scrittura in batch e il numero di operazioni put e delete in una singola operazione di scrittura in batch. Per ulteriori informazioni, consulta [BatchWriteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html). Se la tua richiesta eccede questi limiti, essa verrà rigettata. Se la tua tabella non dispone di sufficiente throughput assegnato per soddisfare questa richiesta, gli elementi di richiesta non eseguiti vengono restituiti nella risposta. 

Il seguente esempio controlla la risposta nel caso in cui vi siano degli elementi di richiesta non eseguiti. Se sono presenti, esegue il loopback e invia nuovamente la richiesta `BatchWriteItem` con gli elementi non elaborati della richiesta. Puoi anche creare queste tabelle di esempio e caricare i dati di esempio in modo programmatico. Per ulteriori informazioni, consulta [Creazione di tabelle di esempio e caricamento di dati utilizzando AWS SDK per .NET](AppendixSampleDataCodeDotNET.md).

Per step-by-step istruzioni su come testare il seguente esempio, vedere[Esempi di codice .NET](CodeSamples.DotNet.md). 

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;

namespace com.amazonaws.codesamples
{
    class LowLevelBatchWrite
    {
        private static string table1Name = "Forum";
        private static string table2Name = "Thread";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                TestBatchWrite();
            }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }

            Console.WriteLine("To continue, press Enter");
            Console.ReadLine();
        }

        private static void TestBatchWrite()
        {
            var request = new BatchWriteItemRequest
            {
                ReturnConsumedCapacity = "TOTAL",
                RequestItems = new Dictionary<string, List<WriteRequest>>
            {
                {
                    table1Name, new List<WriteRequest>
                    {
                        new WriteRequest
                        {
                            PutRequest = new PutRequest
                            {
                                Item = new Dictionary<string, AttributeValue>
                                {
                                    { "Name", new AttributeValue {
                                          S = "S3 forum"
                                      } },
                                    { "Threads", new AttributeValue {
                                          N = "0"
                                      }}
                                }
                            }
                        }
                    }
                },
                {
                    table2Name, new List<WriteRequest>
                    {
                        new WriteRequest
                        {
                            PutRequest = new PutRequest
                            {
                                Item = new Dictionary<string, AttributeValue>
                                {
                                    { "ForumName", new AttributeValue {
                                          S = "S3 forum"
                                      } },
                                    { "Subject", new AttributeValue {
                                          S = "My sample question"
                                      } },
                                    { "Message", new AttributeValue {
                                          S = "Message Text."
                                      } },
                                    { "KeywordTags", new AttributeValue {
                                          SS = new List<string> { "S3", "Bucket" }
                                      } }
                                }
                            }
                        },
                        new WriteRequest
                        {
                            // For the operation to delete an item, if you provide a primary key value
                            // that does not exist in the table, there is no error, it is just a no-op.
                            DeleteRequest = new DeleteRequest
                            {
                                Key = new Dictionary<string, AttributeValue>()
                                {
                                    { "ForumName",  new AttributeValue {
                                          S = "Some partition key value"
                                      } },
                                    { "Subject", new AttributeValue {
                                          S = "Some sort key value"
                                      } }
                                }
                            }
                        }
                    }
                }
            }
            };

            CallBatchWriteTillCompletion(request);
        }

        private static void CallBatchWriteTillCompletion(BatchWriteItemRequest request)
        {
            BatchWriteItemResponse response;

            int callCount = 0;
            do
            {
                Console.WriteLine("Making request");
                response = client.BatchWriteItem(request);
                callCount++;

                // Check the response.

                var tableConsumedCapacities = response.ConsumedCapacity;
                var unprocessed = response.UnprocessedItems;

                Console.WriteLine("Per-table consumed capacity");
                foreach (var tableConsumedCapacity in tableConsumedCapacities)
                {
                    Console.WriteLine("{0} - {1}", tableConsumedCapacity.TableName, tableConsumedCapacity.CapacityUnits);
                }

                Console.WriteLine("Unprocessed");
                foreach (var unp in unprocessed)
                {
                    Console.WriteLine("{0} - {1}", unp.Key, unp.Value.Count);
                }
                Console.WriteLine();

                // For the next iteration, the request will have unprocessed items.
                request.RequestItems = unprocessed;
            } while (response.UnprocessedItems.Count > 0);

            Console.WriteLine("Total # of batch write API calls made: {0}", callCount);
        }
    }
}
```

## Esempio: operazione Batch get utilizzando l'API di AWS SDK per .NET basso livello
<a name="LowLevelDotNetBatchGet"></a>

Il seguente esempio di codice C\$1 utilizza il metodo `BatchGetItem` per recuperare più elementi dalle tabelle `Forum` e `Thread` in Amazon DynamoDB. L'item `BatchGetItemRequest` specifica i nomi delle tabelle e un elenco di chiavi primarie per ogni tabella. Nell'esempio si esegue la risposta stampando gli elementi recuperati. 

Per step-by-step istruzioni su come testare il seguente esempio, vedere[Esempi di codice .NET](CodeSamples.DotNet.md). 

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;

namespace com.amazonaws.codesamples
{
    class LowLevelBatchGet
    {
        private static string table1Name = "Forum";
        private static string table2Name = "Thread";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                RetrieveMultipleItemsBatchGet();

                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }
        }

        private static void RetrieveMultipleItemsBatchGet()
        {
            var request = new BatchGetItemRequest
            {
                RequestItems = new Dictionary<string, KeysAndAttributes>()
            {
                { table1Name,
                  new KeysAndAttributes
                  {
                      Keys = new List<Dictionary<string, AttributeValue> >()
                      {
                          new Dictionary<string, AttributeValue>()
                          {
                              { "Name", new AttributeValue {
                            S = "Amazon DynamoDB"
                        } }
                          },
                          new Dictionary<string, AttributeValue>()
                          {
                              { "Name", new AttributeValue {
                            S = "Amazon S3"
                        } }
                          }
                      }
                  }},
                {
                    table2Name,
                    new KeysAndAttributes
                    {
                        Keys = new List<Dictionary<string, AttributeValue> >()
                        {
                            new Dictionary<string, AttributeValue>()
                            {
                                { "ForumName", new AttributeValue {
                                      S = "Amazon DynamoDB"
                                  } },
                                { "Subject", new AttributeValue {
                                      S = "DynamoDB Thread 1"
                                  } }
                            },
                            new Dictionary<string, AttributeValue>()
                            {
                                { "ForumName", new AttributeValue {
                                      S = "Amazon DynamoDB"
                                  } },
                                { "Subject", new AttributeValue {
                                      S = "DynamoDB Thread 2"
                                  } }
                            },
                            new Dictionary<string, AttributeValue>()
                            {
                                { "ForumName", new AttributeValue {
                                      S = "Amazon S3"
                                  } },
                                { "Subject", new AttributeValue {
                                      S = "S3 Thread 1"
                                  } }
                            }
                        }
                    }
                }
            }
            };

            BatchGetItemResponse response;
            do
            {
                Console.WriteLine("Making request");
                response = client.BatchGetItem(request);

                // Check the response.
                var responses = response.Responses; // Attribute list in the response.

                foreach (var tableResponse in responses)
                {
                    var tableResults = tableResponse.Value;
                    Console.WriteLine("Items retrieved from table {0}", tableResponse.Key);
                    foreach (var item1 in tableResults)
                    {
                        PrintItem(item1);
                    }
                }

                // Any unprocessed keys? could happen if you exceed ProvisionedThroughput or some other error.
                Dictionary<string, KeysAndAttributes> unprocessedKeys = response.UnprocessedKeys;
                foreach (var unprocessedTableKeys in unprocessedKeys)
                {
                    // Print table name.
                    Console.WriteLine(unprocessedTableKeys.Key);
                    // Print unprocessed primary keys.
                    foreach (var key in unprocessedTableKeys.Value.Keys)
                    {
                        PrintItem(key);
                    }
                }

                request.RequestItems = unprocessedKeys;
            } while (response.UnprocessedKeys.Count > 0);
        }

        private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
        {
            foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
            {
                string attributeName = kvp.Key;
                AttributeValue value = kvp.Value;

                Console.WriteLine(
                    attributeName + " " +
                    (value.S == null ? "" : "S=[" + value.S + "]") +
                    (value.N == null ? "" : "N=[" + value.N + "]") +
                    (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
                    (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]")
                    );
            }
            Console.WriteLine("************************************************");
        }
    }
}
```

# Esempio: gestione degli attributi di tipo binario utilizzando l'API di AWS SDK per .NET basso livello
<a name="LowLevelDotNetBinaryTypeExample"></a>

Il seguente esempio di codice C\$1 illustra come gestire gli attributi di tipo binario. L'esempio aggiunge un item alla tabella `Reply`. L'item include un attributo di tipo binario (`ExtendedMessage`) che memorizza i dati compressi. L'esempio recupera quindi l'item e stampa tutti valori degli attributi. A titolo illustrativo, l'esempio usa la classe `GZipStream` per comprimere un flusso di esempio, assegnarlo all'attributo `ExtendedMessage` e per poi decomprimerlo durante la stampa del valore dell'attributo. 

Per step-by-step istruzioni su come testare l'esempio seguente, consulta[Esempi di codice .NET](CodeSamples.DotNet.md). 

**Example**  

```
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;

namespace com.amazonaws.codesamples
{
    class LowLevelItemBinaryExample
    {
        private static string tableName = "Reply";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            // Reply table primary key.
            string replyIdPartitionKey = "Amazon DynamoDB#DynamoDB Thread 1";
            string replyDateTimeSortKey = Convert.ToString(DateTime.UtcNow);

            try
            {
                CreateItem(replyIdPartitionKey, replyDateTimeSortKey);
                RetrieveItem(replyIdPartitionKey, replyDateTimeSortKey);
                // Delete item.
                DeleteItem(replyIdPartitionKey, replyDateTimeSortKey);
                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }
        }

        private static void CreateItem(string partitionKey, string sortKey)
        {
            MemoryStream compressedMessage = ToGzipMemoryStream("Some long extended message to compress.");
            var request = new PutItemRequest
            {
                TableName = tableName,
                Item = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      S = partitionKey
                  }},
                { "ReplyDateTime", new AttributeValue {
                      S = sortKey
                  }},
                { "Subject", new AttributeValue {
                      S = "Binary type "
                  }},
                { "Message", new AttributeValue {
                      S = "Some message about the binary type"
                  }},
                { "ExtendedMessage", new AttributeValue {
                      B = compressedMessage
                  }}
            }
            };
            client.PutItem(request);
        }

        private static void RetrieveItem(string partitionKey, string sortKey)
        {
            var request = new GetItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      S = partitionKey
                  } },
                { "ReplyDateTime", new AttributeValue {
                      S = sortKey
                  } }
            },
                ConsistentRead = true
            };
            var response = client.GetItem(request);

            // Check the response.
            var attributeList = response.Item; // attribute list in the response.
            Console.WriteLine("\nPrinting item after retrieving it ............");

            PrintItem(attributeList);
        }

        private static void DeleteItem(string partitionKey, string sortKey)
        {
            var request = new DeleteItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      S = partitionKey
                  } },
                { "ReplyDateTime", new AttributeValue {
                      S = sortKey
                  } }
            }
            };
            var response = client.DeleteItem(request);
        }

        private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
        {
            foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
            {
                string attributeName = kvp.Key;
                AttributeValue value = kvp.Value;

                Console.WriteLine(
                    attributeName + " " +
                    (value.S == null ? "" : "S=[" + value.S + "]") +
                    (value.N == null ? "" : "N=[" + value.N + "]") +
                    (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
                    (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]") +
                    (value.B == null ? "" : "B=[" + FromGzipMemoryStream(value.B) + "]")
                    );
            }
            Console.WriteLine("************************************************");
        }

        private static MemoryStream ToGzipMemoryStream(string value)
        {
            MemoryStream output = new MemoryStream();
            using (GZipStream zipStream = new GZipStream(output, CompressionMode.Compress, true))
            using (StreamWriter writer = new StreamWriter(zipStream))
            {
                writer.Write(value);
            }
            return output;
        }

        private static string FromGzipMemoryStream(MemoryStream stream)
        {
            using (GZipStream zipStream = new GZipStream(stream, CompressionMode.Decompress))
            using (StreamReader reader = new StreamReader(zipStream))
            {
                return reader.ReadToEnd();
            }
        }
    }
}
```