

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# PartiQL：一種適用於 Amazon DynamoDB 的 SQL 相容查詢語言
<a name="ql-reference"></a>

Amazon DynamoDB 支援 [PartiQL](https://partiql.org/) (SQL 相容查詢語言)，可在 Amazon DynamoDB 中選取、插入、更新和刪除資料。使用 PartiQL，您可以輕鬆地與 DynamoDB 資料表互動 AWS Command Line Interface，並使用 PartiQL 的 AWS 管理主控台、NoSQL Workbench 和 DynamoDB APIs 執行臨機操作查詢。

PartiQL 操作提供與其他 DynamoDB 資料平面操作相同的可用性、延遲和效能。

下列各節將介紹 PartiQL 的 DynamoDB 實作。

**Topics**
+ [什麼是 PartiQL？](#ql-reference.what-is)
+ [Amazon DynamoDB 中的 PartiQL](#ql-reference.what-is)
+ [開始使用](ql-gettingstarted.md)
+ [資料類型](ql-reference.data-types.md)
+ [陳述式](ql-reference.statements.md)
+ [函數](ql-functions.md)
+ [運算子](ql-operators.md)
+ [交易](ql-reference.multiplestatements.transactions.md)
+ [批次操作](ql-reference.multiplestatements.batching.md)
+ [IAM 政策](ql-iam.md)

## 什麼是 PartiQL？
<a name="ql-reference.what-is"></a>

*PartiQL* 在包含結構化資料、半結構化資料和巢狀資料的多個資料存放區提供與 SQL 相容的查詢存取。它在 Amazon 中廣泛使用，現在可做為許多 AWS 服務的一部分使用，包括 DynamoDB。

如需 PartiQL 規範和核心查詢語言的教學課程，請參閱 [PartiQL 文件](https://partiql.org/docs.html)。

**注意**  
Amazon DynamoDB 支援 [PartiQL](https://partiql.org/) 查詢語言的*子集*。
Amazon DynamoDB 不支援 [Amazon Ion](http://amzn.github.io/ion-docs/) 資料格式或 Amazon Ion 文字。

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

若要在 DynamoDB 中執行 PartiQL 查詢，您可以使用：
+ DynamoDB 主控台
+ NoSQL Workbench
+ The AWS Command Line Interface (AWS CLI)
+ DynamoDB API

如需使用這些方法存取 DynamoDB 的相關資訊，請參閱[存取 DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AccessingDynamoDB.html)。

# DynamoDB 專用 PartiQL 入門
<a name="ql-gettingstarted"></a>

本節說明如何從 Amazon DynamoDB 主控台、 AWS Command Line Interface (AWS CLI) 和 DynamoDB API 使用 DynamoDB 專用 PartiQL。

在下列範例中，[DynamoDB 入門](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html)教學課程中所定義的 DynamoDB 資料表是先決條件。

如需有關使用 DynamoDB 主控台 AWS Command Line Interface或 DynamoDB APIs 存取 DynamoDB 的資訊，請參閱[存取 DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AccessingDynamoDB.html)。

若要[下載](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.settingup.html)並使用 [NoSQL Workbench](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.html) 來建置 [DynamoDB 專用 PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) 陳述式，請選擇位於 NoSQL Workbench for DynamoDB [Operation Builder](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.querybuilder.operationbuilder.html) 右上角的 **PartiQL operations** (PartiQL 操作)。

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

![\[PartiQL 編輯器介面，顯示在 Music 資料表上執行查詢操作的結果。\]](http://docs.aws.amazon.com/zh_tw/amazondynamodb/latest/developerguide/images/partiqlgettingstarted.png)


1. 登入 AWS 管理主控台 ，並在 https：//[https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/) 開啟 DynamoDB 主控台。

1. 在主控台左側的導覽窗格中，選擇 **PartiQL editor** (PartiQL 編輯器)。

1. 選擇 **Music** (音樂) 資料表。

1. 選擇 **Query table** (查詢資料表)。此動作會產生不會導致完整資料表掃描的查詢。

1. 使用字串值 `Acme Band` 取代 `partitionKeyValue`。使用字串值 `Happy Day` 取代 `sortKeyValue`。

1. 選擇 **Run** (執行) 按鈕。

1. 您可以選擇 **Table view** (資料表檢視) 或 **JSON view** (JSON 檢視) 按鈕來檢視查詢的結果。

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

![\[NoSQL Workbench 介面。它會顯示 PartiQL SELECT 陳述式，您可以在 Music 資料表上執行。\]](http://docs.aws.amazon.com/zh_tw/amazondynamodb/latest/developerguide/images/workbench/partiql.single.png)


1. 選擇 **PartiQL statement** (PartiQL 陳述式)。

1. 輸入下列 PartiQL [SELECT 陳述式](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.select.html) 

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

1. 若要指定 `Artist` 和 `SongTitle` 參數的值：

   1. 選擇 **Optional request parameters** (選用的請求參數)。

   1. 選擇 **Add new parameters** (新增新參數)。

   1. 選擇屬性類型 **string** 和數值 `Acme Band`。

   1.  重複步驟 b 和 c，然後選擇類型 **string** 和數值 `PartiQL Rocks`。

1. 若要產生程式碼，請選擇 **Generate code** (產生程式碼)。

   從顯示的標籤中選取所需的語言。您現在可以複製此程式碼，並使用在您的應用程式中。

1. 若希望立即執行此操作，請選擇 **Run** (執行)。

------
#### [ AWS CLI ]

1. 使用 INSERT PartiQL 陳述式在 `Music` 資料表中建立項目。

   ```
   aws dynamodb execute-statement --statement "INSERT INTO Music  \
   					    VALUE  \
   					    {'Artist':'Acme Band','SongTitle':'PartiQL Rocks'}"
   ```

1. 使用 SELECT PartiQL 陳述式從 Music 資料表中檢索項目。

   ```
   aws dynamodb execute-statement --statement "SELECT * FROM Music   \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

1. 使用 UPDATE PartiQL 陳述式在 `Music` 資料表中更新項目。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardsWon=1  \
                                               SET AwardDetail={'Grammys':[2020, 2018]}  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   在 `Music` 資料表中新增項目的清單值。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   在 `Music` 資料表中移除項目的清單值。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               REMOVE AwardDetail.Grammys[2]  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   在 `Music` 資料表中新增項目的新映射成員。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardDetail.BillBoard=[2020]  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   在 `Music` 資料表中新增項目的新字串集屬性。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET BandMembers =<<'member1', 'member2'>>  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   在 `Music` 資料表中更新項目的字串集屬性。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET BandMembers =set_add(BandMembers, <<'newmember'>>)  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

1. 使用刪除 PartiQL 陳述式從 `Music` 資料表中刪除項目。

   ```
   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());
        }
    }

}
```

------

## 使用參數化陳述式
<a name="ql-gettingstarted.parameterized"></a>

您可以使用問號 (`?`) 預留位置，並在 `Parameters` 欄位中分別提供值，而不是直接在 PartiQL 陳述式字串中內嵌值。每個 `?` 都會依提供的順序，以對應的參數值取代。

使用參數化陳述式是最佳實務，因為它會將陳述式結構與資料值分開，讓陳述式更容易閱讀和重複使用。它也不需要在陳述式字串中手動格式化和逸出屬性值。

`ExecuteStatement`、 `BatchExecuteStatement`和 `ExecuteTransaction`操作支援參數化陳述式。

下列範例使用分割區索引鍵和排序索引鍵的參數化值，從`Music`資料表中擷取項目。

------
#### [ 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'}
    ]
)
```

------

**注意**  
上一節中的 Java 範例使用參數化陳述式。`getPartiQLParameters()` 方法會建置參數清單，而每個陳述式會使用`?`預留位置而非內嵌值。

# 適用於 DynamoDB 的 PartiQL 資料類型
<a name="ql-reference.data-types"></a>

下表列出您可搭配 DynamoDB 專用 PartiQL 使用的資料類型。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/amazondynamodb/latest/developerguide/ql-reference.data-types.html)

## 範例
<a name="ql-reference.data-types"></a>

下述陳述式示範如何插入以下資料類型：`String`、`Number`、`Map`、`List`、`Number Set` 和 `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'>>
}
```

下述陳述式示範如何將新的元素插入 `Map`、`List`、`Number Set` 和 `String Set` 類型，並變更 `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'
```

下述陳述式示範如何從 `Map`、`List`、`Number Set` 和 `String Set` 類型移除元素，並變更 `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'
```

如需詳細資訊，請參閱 [DynamoDB 資料類型](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes)。

# 適用於 DynamoDB 的 PartiQL 陳述式
<a name="ql-reference.statements"></a>

Amazon DynamoDB 支援下列 PartiQL 陳述式。

**注意**  
DynamoDB 不支援所有 PartiQL 陳述式。  
此參考提供使用 AWS CLI 或 APIs 手動執行之 PartiQL 陳述式的基本語法和使用範例。

*資料操作語言* (DML) 是一組用來管理 DynamoDB 資料表中資料的 PartiQL 陳述式。您可使用 DML 陳述式新增、修改或刪除資料表中的資料。

支援下列 DML 和查詢語言陳述式：
+ [適用於 DynamoDB 的 PartiQL Select 陳述式](ql-reference.select.md)
+ [適用於 DynamoDB 的 PartiQL Update 陳述式](ql-reference.update.md)
+ [適用於 DynamoDB 的 PartiQL Insert 陳述式](ql-reference.insert.md)
+ [適用於 DynamoDB 的 PartiQL Delete 陳述式](ql-reference.delete.md)

DynamoDB 專用 PartiQL 亦支援 [使用 DynamoDB 專用 PartiQL 執行交易](ql-reference.multiplestatements.transactions.md) 和 [使用 DynamoDB 專用 PartiQL 執行批次操作](ql-reference.multiplestatements.batching.md)。

# 適用於 DynamoDB 的 PartiQL Select 陳述式
<a name="ql-reference.select"></a>

在 Amazon DynamoDB 中，使用 `SELECT` 陳述式從資料表檢索資料。

如果 WHERE 子句中未提供與分割區索引鍵相等或 IN 條件，使用 `SELECT` 陳述式可能會導致完整的資料表掃描。掃描操作會檢查每個項目的要求值，並可能會在單一操作中耗用大型資料表或索引的佈建輸送量。

如果您想避免在 PartiQL 中進行完整的資料表掃描，則可以：
+ 確保 [WHERE 子句條件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.select.html#ql-reference.select.parameters)會據此進行相應設定，撰寫您的 `SELECT` 陳述式便不會導致完整的資料表掃描。
+ 請使用《DynamoDB 開發人員指南》中 [範例：允許在 DynamoDB 專用 PartiQL 中執行選取陳述式並拒絕完整的資料表掃描陳述式](ql-iam.md#access-policy-ql-iam-example6) 所述的 IAM 政策來停用完整的資料表掃描。

如需詳細資訊，請參閱《DynamoDB 開發人員指南》中的[查詢和掃描資料的最佳實務](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-query-scan.html)。

**Topics**
+ [語法](#ql-reference.select.syntax)
+ [Parameters](#ql-reference.select.parameters)
+ [範例](#ql-reference.select.examples)

## 語法
<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>

***表達式***  
(必要) 從 `*` 萬用字元形成的投影，或來自結果集中一或多個屬性名稱或文件路徑的投影清單。一個表達式可以包含對 [搭配 DynamoDB 使用 PartiQL 函數](ql-functions.md) 的呼叫或由 [適用於 DynamoDB 的 PartiQL 算術、比較和邏輯運算子](ql-operators.md) 修改的欄位。

***資料表***  
(必要) 要查詢的資料表名稱。

***索引***  
(選用) 要查詢的索引名稱。  
查詢索引時，必須在資料表名稱和索引名稱上加上雙引號。  

```
SELECT * 
FROM "TableName"."IndexName"
```

***condition***  
(選用) 查詢的選取條件。  
若要確保 `SELECT` 陳述式不會導致完整的資料表掃描，`WHERE` 子句條件必須指定分割區索引鍵。使用等於或 IN 運算子。  
例如，如果一個 `Orders` 資料表包含 `OrderID` 分割區索引鍵和其他非索引鍵屬性 (包括 `Address`)，則下列陳述式不會導致完整的資料表掃描：  

```
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]
```
不過，下列 `SELECT` 陳述式會導致完整的資料表掃描：  

```
SELECT * 
FROM "Orders" 
WHERE OrderID > 1

SELECT * 
FROM "Orders" 
WHERE Address='some address'

SELECT * 
FROM "Orders" 
WHERE OrderID = 100 OR Address='some address'
```

***金鑰***  
(選用) 用來排序傳回結果的雜湊索引鍵或排序索引鍵。預設順序是升序 (`ASC`)；如果您希望依降序傳回結果，請指定 `DESC`。

**注意**  
如果您省略 `WHERE` 子句，則會檢索資料表中的所有項目。

## 範例
<a name="ql-reference.select.examples"></a>

如果存在一個項目，則下列查詢會指定分割區索引鍵和 `OrderID` 並使用等於運算子，從 `Orders` 資料表傳回一個項目。

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID = 1
```

下列查詢會針對具有特定分割區索引鍵、`OrderID` 和值的 `Orders` 資料表，使用 OR 運算子傳回其中的所有項目。

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID = 1 OR OrderID = 2
```

下列查詢會針對具有特定分割區索引鍵、`OrderID` 和值的 `Orders` 資料表，使用 IN 運算子傳回其中的所有項目。傳回的結果會根據 `OrderID` 索引鍵屬性值以遞減順序顯示。

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID IN [1, 2, 3] ORDER BY OrderID DESC
```

下列查詢顯示完整的資料表掃描，該掃描會傳回 `Orders` 資料表中 `Total` 大於 500 的所有項目，其中 `Total` 是非索引鍵屬性。

```
SELECT OrderID, Total 
FROM "Orders"
WHERE Total > 500
```

下列查詢顯示完整的資料表掃描，該掃描會傳回使用 IN 運算子和非索引鍵屬性 `Total` 之特定 `Total` 順序範圍內 `Orders` 資料表中的所有項目。

```
SELECT OrderID, Total 
FROM "Orders"
WHERE Total IN [500, 600]
```

下列查詢顯示完整的資料表掃描，該掃描會傳回使用 BETWEEN 運算子和非索引鍵屬性 `Total` 之特定 `Total` 順序範圍內 `Orders` 資料表中的所有項目。

```
SELECT OrderID, Total 
FROM "Orders" 
WHERE Total BETWEEN 500 AND 600
```

下列查詢會在 WHERE 子句條件中指定分割區索引鍵 `CustomerID` 和排序索引鍵 `MovieID`，並在 SELECT 子句中使用文件路徑，以此傳回 FireStick 裝置用於觀看的第一個日期。

```
SELECT Devices.FireStick.DateWatched[0] 
FROM WatchList 
WHERE CustomerID= 'C1' AND MovieID= 'M1'
```

下列查詢會顯示完整的資料表掃描，該掃描會使用 WHERE 子句條件中的文件路徑傳回在 2019 年 12 月 24 日之後首次使用 FireStick 裝置的項目清單。

```
SELECT Devices 
FROM WatchList 
WHERE Devices.FireStick.DateWatched[0] >= '12/24/19'
```

# 適用於 DynamoDB 的 PartiQL Update 陳述式
<a name="ql-reference.update"></a>

使用 `UPDATE` 陳述式來修改 Amazon DynamoDB 資料表中項目內一或多個屬性的值。

**注意**  
您一次只能更新一個項目，因為您無法發出可刪除多個項目的單個 DynamoDB PartiQL 陳述式。如需更新多個項目的相關資訊，請參閱 [使用 DynamoDB 專用 PartiQL 執行交易](ql-reference.multiplestatements.transactions.md) 或 [使用 DynamoDB 專用 PartiQL 執行批次操作](ql-reference.multiplestatements.batching.md)。

**Topics**
+ [語法](#ql-reference.update.syntax)
+ [Parameters](#ql-reference.update.parameters)
+ [傳回值](#ql-reference.update.return)
+ [範例](#ql-reference.update.examples)

## 語法
<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>

***資料表***  
(必要) 包含要修改之資料的資料表。

***路徑***  
(必要) 要建立或修改的屬性名稱或文件路徑。

***資料***  
(必要) 屬性值或操作的結果。  
與 SET 搭配使用的支援操作：  
+ LIST\$1APPEND：將數值新增至清單類型。
+ SET\$1ADD：將數值新增至數字或字串集。
+ SET\$1DELETE：從數字或字串集中刪除數值。

***condition***  
(必要) 要修改之項目的選取條件。此條件必須解析為單一主索引鍵值。

***returnvalues***  
(選用) 若想取得更新之前或之後出現的項目屬性，則請使用 `returnvalues`。有效值為：  
+ `ALL OLD *`：傳回更新操作之前出現的所有項目屬性。
+ `MODIFIED OLD *`：僅傳回新操作之前出現的更新屬性。
+ `ALL NEW *`：傳回更新操作之後出現的所有項目屬性。
+ `MODIFIED NEW *`：僅傳回 `UpdateItem` 操作之後出現的更新屬性。

## 傳回值
<a name="ql-reference.update.return"></a>

此陳述式不會傳回值，除非指定 `returnvalues` 參數。

**注意**  
如果 DynamoDB 資料表中任何項目的 UPDATE 陳述式的 WHERE 子句未評估為 true，則會傳回 `ConditionalCheckFailedException`。

## 範例
<a name="ql-reference.update.examples"></a>

更新現有項目中的屬性值。如果屬性不存在，則會建立此屬性。

下列查詢會透過新增數字類型的屬性 (`AwardsWon`) 和映射類型的屬性 (`AwardDetail`) 來更新 `"Music"` 資料表中的項目。

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

您可以新增 `RETURNING ALL OLD *` 以傳回 `Update` 操作前顯示的屬性。

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
RETURNING ALL OLD *
```

這會傳回下列內容：

```
{
    "Items": [
        {
            "Artist": {
                "S": "Acme Band"
            },
            "SongTitle": {
                "S": "PartiQL Rocks"
            }
        }
    ]
}
```

您可以新增 `RETURNING ALL NEW *` 以傳回 `Update` 操作後顯示的屬性。

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
RETURNING ALL NEW *
```

這會傳回下列內容：

```
{
    "Items": [
        {
            "AwardDetail": {
                "M": {
                    "Grammys": {
                        "L": [
                            {
                                "N": "2020"
                            },
                            {
                                "N": "2018"
                            }
                        ]
                    }
                }
            },
            "AwardsWon": {
                "N": "1"
            }
        }
    ]
}
```

下列查詢會透過附加至清單 `AwardDetail.Grammys` 來更新 `"Music"` 中的項目。

```
UPDATE "Music" 
SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

下列查詢會透過從清單 `AwardDetail.Grammys` 中移除來更新 `"Music"` 資料表中的項目。

```
UPDATE "Music" 
REMOVE AwardDetail.Grammys[2]   
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

下列查詢會透過將 `BillBoard` 新增至映射 `AwardDetail` 來更新 `"Music"` 資料表中的項目。

```
UPDATE "Music" 
SET AwardDetail.BillBoard=[2020] 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

下列查詢會透過新增字串集屬性 `BandMembers` 來更新 `"Music"` 資料表中的項目。

```
UPDATE "Music" 
SET BandMembers =<<'member1', 'member2'>> 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

下列查詢會透過將 `newbandmember` 新增至字串集 `BandMembers` 來更新 `"Music"` 資料表中的項目。

```
UPDATE "Music" 
SET BandMembers =set_add(BandMembers, <<'newbandmember'>>) 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

# 適用於 DynamoDB 的 PartiQL Delete 陳述式
<a name="ql-reference.delete"></a>

使用 `DELETE` 陳述式從您的 Amazon DynamoDB 資料表中刪除現有項目。

**注意**  
您一次只能刪除一個項目。您無法發出可刪除多個項目的單個 DynamoDB PartiQL 陳述式。如需刪除多個項目的相關資訊，請參閱 [使用 DynamoDB 專用 PartiQL 執行交易](ql-reference.multiplestatements.transactions.md) 或 [使用 DynamoDB 專用 PartiQL 執行批次操作](ql-reference.multiplestatements.batching.md)。

**Topics**
+ [語法](#ql-reference.delete.syntax)
+ [Parameters](#ql-reference.delete.parameters)
+ [傳回值](#ql-reference.delete.return)
+ [範例](#ql-reference.delete.examples)

## 語法
<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>

***資料表***  
(必要) 包含要刪除之項目的 DynamoDB 資料表。

***condition***  
(必要) 要刪除之項目的選取條件；此條件必須解析為單一主索引鍵值。

***returnvalues***  
(選用) 若想取得在刪除之前出現的項目屬性，則請使用 `returnvalues`。有效值為：  
+ `ALL OLD *`：傳回舊項目的內容。

## 傳回值
<a name="ql-reference.delete.return"></a>

此陳述式不會傳回值，除非指定 `returnvalues` 參數。

**注意**  
如果 DynamoDB 資料表沒有任何與發出 DELETE 的項目具有相同主索引鍵的項目，則會傳回 SUCCESS，並刪除 0 個項目。如果資料表具有相同主索引鍵的項目，但 DELETE 陳述式的 WHERE 子句中的條件評估結果為 false，則會傳回 `ConditionalCheckFailedException`。

## 範例
<a name="ql-reference.delete.examples"></a>

下列查詢會刪除 `"Music"` 資料表中的一個項目。

```
DELETE FROM "Music" WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks'
```

您可以新增參數 `RETURNING ALL OLD *` 以傳回已刪除的資料。

```
DELETE FROM "Music" WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks' RETURNING ALL OLD *
```

`Delete` 陳述式現在傳回下列內容：

```
{
    "Items": [
        {
            "Artist": {
                "S": "Acme Band"
            },
            "SongTitle": {
                "S": "PartiQL Rocks"
            }
        }
    ]
}
```

# 適用於 DynamoDB 的 PartiQL Insert 陳述式
<a name="ql-reference.insert"></a>

使用 `INSERT` 陳述式在 Amazon DynamoDB 中將項目新增至資料表。

**注意**  
您一次只能插入一個項目，因為您無法發出可插入多個項目的單個 DynamoDB PartiQL 陳述式。如需插入多個項目的相關資訊，請參閱 [使用 DynamoDB 專用 PartiQL 執行交易](ql-reference.multiplestatements.transactions.md) 或 [使用 DynamoDB 專用 PartiQL 執行批次操作](ql-reference.multiplestatements.batching.md)。

**Topics**
+ [語法](#ql-reference.insert.syntax)
+ [Parameters](#ql-reference.insert.parameters)
+ [傳回值](#ql-reference.insert.return)
+ [範例](#ql-reference.insert.examples)

## 語法
<a name="ql-reference.insert.syntax"></a>

插入單一項目。

```
INSERT INTO table VALUE item
```

## Parameters
<a name="ql-reference.insert.parameters"></a>

***資料表***  
(必要) 您要插入資料的資料表。索資料表必須已存在。

***項目***  
(必要) 有效的 DynamoDB 項目表示為 [PartiQL 元組](https://partiql.org/docs.html)。您必須在 PartiQL 中僅指定*一個*項目，項目中的每個屬性名稱均區分大小寫，且可以使用*單*引號 (`'...'`) 表示。  
PartiQL 中的字串值也使用*單*引號 (`'...'`) 表示。

## 傳回值
<a name="ql-reference.insert.return"></a>

此陳述式不會傳回任何值。

**注意**  
如果 DynamoDB 資料表已經有一個項目的主索引鍵與插入的項目的主索引鍵相同，則會傳回 `DuplicateItemException`。

## 範例
<a name="ql-reference.insert.examples"></a>

```
INSERT INTO "Music" value {'Artist' : 'Acme Band','SongTitle' : 'PartiQL Rocks'}
```

# 搭配 DynamoDB 使用 PartiQL 函數
<a name="ql-functions"></a>

Amazon DynamoDB 中的 PartiQL 支援下列 SQL 標準函數的內建變體。

**注意**  
DynamoDB 目前不支援任何未包含在此清單中的 SQL 函數。

## 彙總函數
<a name="ql-functions.aggregate"></a>
+ [搭配 Amazon DynamoDB 專用 PartiQL 使用 SIZE 函數](ql-functions.size.md)

## 條件函數
<a name="ql-functions.conditional"></a>
+ [搭配 DynamoDB 專用 PartiQL 使用 EXISTS 函數](ql-functions.exists.md)
+ [搭配 DynamoDB 專用 PartiQL 使用 ATTRIBUTE\$1TYPE 函數](ql-functions.attribute_type.md)
+ [搭配 DynamoDB 專用 PartiQL 使用 BEGINS\$1WITH 函數](ql-functions.beginswith.md)
+ [搭配 DynamoDB 專用 PartiQL 使用 CONTAINS 函數](ql-functions.contains.md)
+ [搭配 DynamoDB 專用 PartiQL 使用 MISSING 函數](ql-functions.missing.md)

# 搭配 DynamoDB 專用 PartiQL 使用 EXISTS 函數
<a name="ql-functions.exists"></a>

您可以使用 EXISTS 來執行與 `ConditionCheck` 會在 [TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems) API 中執行的相同函數。EXISTS 函數只能在交易中使用。

給定一個值，如果該值是一個非空集合，則傳回 `TRUE`。如果不是，則傳回 `FALSE`。

**注意**  
此函數只能在交易操作中使用。

## 語法
<a name="ql-functions.exists.syntax"></a>

```
EXISTS ( statement )
```

## 引數
<a name="ql-functions.exists.arguments"></a>

*陳述式*  
(必要) 函數評估的 SELECT 陳述式。  
SELECT 陳述式必須指定完整的主索引鍵和其他一個條件。

## 傳回類型
<a name="ql-functions.exists.return-type"></a>

`bool`

## 範例
<a name="ql-functions.exists.examples"></a>

```
EXISTS(
    SELECT * FROM "Music" 
    WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks')
```

# 搭配 DynamoDB 專用 PartiQL 使用 BEGINS\$1WITH 函數
<a name="ql-functions.beginswith"></a>

如果指定的屬性以特定子字串開頭，則傳回 `TRUE`。

## 語法
<a name="ql-functions.beginswith.syntax"></a>

```
begins_with(path, value )
```

## 引數
<a name="ql-functions.beginswith.arguments"></a>

*路徑*  
(必要) 要使用的屬性名稱或文件路徑。

*值*  
(必要) 要搜尋的字串。

## 傳回類型
<a name="ql-functions.beginswith.return-type"></a>

`bool`

## 範例
<a name="ql-functions.beginswith.examples"></a>

```
SELECT * FROM "Orders" WHERE "OrderID"=1 AND begins_with("Address", '7834 24th')
```

# 搭配 DynamoDB 專用 PartiQL 使用 MISSING 函數
<a name="ql-functions.missing"></a>

如果項目不包含指定的屬性，即傳回 `TRUE`。只有等於和不等於運算子可以與此函數一起使用。

## 語法
<a name="ql-functions.missing.syntax"></a>

```
 attributename IS | IS NOT  MISSING 
```

## 引數
<a name="ql-functions.missing.arguments"></a>

*attributename*  
(必要) 要尋找的屬性名稱。

## 傳回類型
<a name="ql-functions.missing.return-type"></a>

`bool`

## 範例
<a name="ql-functions.missing.examples"></a>

```
SELECT * FROM Music WHERE "Awards" is MISSING
```

# 搭配 DynamoDB 專用 PartiQL 使用 ATTRIBUTE\$1TYPE 函數
<a name="ql-functions.attribute_type"></a>

如果指定路徑的屬性是特定資料類型，則傳回 `TRUE`。

## 語法
<a name="ql-functions.attribute_type.syntax"></a>

```
attribute_type( attributename, type )
```

## 引數
<a name="ql-functions.attribute_type.arguments"></a>

*attributename*  
(必要) 要使用的屬性名稱。

*類型*  
(必要) 要檢查的屬性類型。如需有效值的清單，請參閱 DynamoDB [attribute\$1type](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions)。

## 傳回類型
<a name="ql-functions.attribute_type.return-type"></a>

`bool`

## 範例
<a name="ql-functions.attribute_type.examples"></a>

```
SELECT * FROM "Music" WHERE attribute_type("Artist", 'S')
```

# 搭配 DynamoDB 專用 PartiQL 使用 CONTAINS 函數
<a name="ql-functions.contains"></a>

如果路徑指定的屬性為下列其中一個項目，則傳回 `TRUE`：
+ 包含特定子字串的字串。
+ 在組合中內含特定元素的組合。

如需詳細資訊，請參閱 DynamoDB 的 [contains](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) 函數。

## 語法
<a name="ql-functions.contains.syntax"></a>

```
contains( path, substring )
```

## 引數
<a name="ql-functions.contains.arguments"></a>

*路徑*  
(必要) 要使用的屬性名稱或文件路徑。

*子字串*  
(必要) 要檢查的屬性子字串或集合成員。如需詳細資訊，請參閱 DynamoDB 的 [contains](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) 函數。

## 傳回類型
<a name="ql-functions.contains.return-type"></a>

`bool`

## 範例
<a name="ql-functions.contains.examples"></a>

```
SELECT * FROM "Orders" WHERE "OrderID"=1 AND contains("Address", 'Kirkland')
```

# 搭配 Amazon DynamoDB 專用 PartiQL 使用 SIZE 函數
<a name="ql-functions.size"></a>

傳回代表屬性大小的數字 (以位元組為單位)。以下是可搭配 size 使用的有效資料類型。如需詳細資訊，請參閱 DynamoDB 的 [size](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) 函數。

## 語法
<a name="ql-functions.size.syntax"></a>

```
size( path)
```

## 引數
<a name="ql-functions.size.arguments"></a>

*路徑*  
(必要) 屬性名稱或文件路徑。  
如需了解支援的類型，請參閱 DynamoDB [size](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) 函數。

## 傳回類型
<a name="ql-functions.size.return-type"></a>

`int`

## 範例
<a name="ql-functions.size.examples"></a>

```
 SELECT * FROM "Orders" WHERE "OrderID"=1 AND size("Image") >300
```

# 適用於 DynamoDB 的 PartiQL 算術、比較和邏輯運算子
<a name="ql-operators"></a>

Amazon DynamoDB 中的 PartiQL 支援以下 [SQL 標準運算子](https://www.w3schools.com/sql/sql_operators.asp)。

**注意**  
DynamoDB 目前不支援任何未包含在此清單中的 SQL 運算子。

## 算術運算子
<a name="ql-operators.arithmetic"></a>


****  

| 運算子 | Description | 
| --- | --- | 
| \$1 | 加 | 
| - | 減 | 

## 比較運算子
<a name="ql-operators.comparison"></a>


****  

| 運算子 | Description | 
| --- | --- | 
| = | 等於 | 
| <> | 不等於 | 
| \$1= | 不等於 | 
| > | Greater than | 
| < | Less than | 
| >= | 大於或等於 | 
| <= | 小於或等於 | 

## 邏輯運算子
<a name="ql-operators.logical"></a>


****  

| 運算子 | Description | 
| --- | --- | 
| AND | 如果以 AND 分隔的所有的條件為 TRUE，則為 TRUE | 
| BETWEEN |  如果運算元在比較範圍內，則為 `TRUE`。 此運算子包含您套用運算元的下限和上限。  | 
| IN | `TRUE` 如果運算元等於表達式清單之一 （上限為 50 個雜湊屬性值或上限為 100 個非索引鍵屬性值）。 結果會以最多 10 個項目的頁面傳回。如果`IN`清單包含更多值，您必須使用回應中`NextToken`傳回的 來擷取後續頁面。 | 
| IS | 如果運算元是給定的 PartiQL 資料類型 (包括 NULL 或 MISSING)，則為 TRUE | 
| NOT | 反轉指定布林表達式的值 | 
| OR | 如果以 OR 分隔任何的條件為 TRUE，則為 TRUE | 

如需邏輯運算子的詳細資訊，請參閱 [進行比較](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.Comparators) 和 [邏輯評估](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.LogicalEvaluations)。

# 使用 DynamoDB 專用 PartiQL 執行交易
<a name="ql-reference.multiplestatements.transactions"></a>

本節說明如何搭配 DynamoDB 專用 PartiQL 使用交易。PartiQL 交易限制為全部 100 個陳述式 (動作)。

如需 DynamoDB 交易的詳細資訊，請參閱[管理包含 DynamoDB 交易的複雜工作流程](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html)。

**注意**  
整個交易必須由讀取陳述式或寫入陳述式所組成。你不能在一個交易中混合兩者。EXISTS 函數為例外。可用類似於 [TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems) API 操作中的 `ConditionCheck` 方式檢查項目特定屬性的條件。

**Topics**
+ [語法](#ql-reference.multiplestatements.transactions.syntax)
+ [Parameters](#ql-reference.multiplestatements.transactions.parameters)
+ [傳回值](#ql-reference.multiplestatements.transactions.return)
+ [範例](#ql-reference.multiplestatements.transactions.examples)

## 語法
<a name="ql-reference.multiplestatements.transactions.syntax"></a>

```
[
   {
      "Statement":" statement ",
      "Parameters":[
         {
            " parametertype " : " parametervalue "
         }, ...]
   } , ...
]
```

## Parameters
<a name="ql-reference.multiplestatements.transactions.parameters"></a>

***陳述式***  
(必要) DynamoDB 專用 PartiQL 支援的陳述式。  
整個交易必須由讀取陳述式或寫入陳述式所組成。你不能在一個交易中混合兩者。

***parametertype***  
(選用) DynamoDB 類型，如果在指定 PartiQL 陳述式時使用了參數。

***parametervalue***  
(選用) 參數值，如果在指定 PartiQL 陳述式時使用了參數。

## 傳回值
<a name="ql-reference.multiplestatements.transactions.return"></a>

此陳述式不會傳回寫入作業 (插入、更新或刪除) 的任何值。但是，它根據 WHERE 子句中指定的條件回傳讀取操作 (SELECT) 的不同值。

**注意**  
如果任何單一 INSERT、UPDATE 或 DELETE 操作傳回錯誤，交易會取消並出現 `TransactionCanceledException` 例外狀況，且取消原因程式碼會包含個別單一操作的錯誤。

## 範例
<a name="ql-reference.multiplestatements.transactions.examples"></a>

以下範例會以交易形式執行多個陳述式。

------
#### [ AWS CLI ]

1. 將以下 JSON 程式碼儲存至名為 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. 在命令提示中執行下列命令。

   ```
   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());
        }
    }

}
```

------

下列範例顯示當 DynamoDB 讀取 WHERE 子句中指定之不同條件的項目時，不同的傳回值。

------
#### [ AWS CLI ]

1. 將以下 JSON 程式碼儲存至名為 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.  在命令提示中執行命令。

   ```
   aws dynamodb execute-transaction --transact-statements  file://partiql.json
   ```

1. 會傳回下列回應：

   ```
   {
       "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
           {}
       ]
   }
   ```

------

# 使用 DynamoDB 專用 PartiQL 執行批次操作
<a name="ql-reference.multiplestatements.batching"></a>

本節說明如何搭配 DynamoDB 專用 PartiQL 使用批次陳述式。

**注意**  
整個批次必須由讀取陳述式或寫入陳述式所組成；一個批次中不能同時出現這兩種陳述式樣。
`BatchExecuteStatement` 和 `BatchWriteItem` 每個批次不可以執行超過 25 條陳述式。
`BatchExecuteStatement` 會使用 `BatchGetItem`，其會取得個別陳述式中主索引鍵的清單。

**Topics**
+ [語法](#ql-reference.multiplestatements.batching.syntax)
+ [Parameters](#ql-reference.multiplestatements.batching.parameters)
+ [範例](#ql-reference.multiplestatements.batching.examples)

## 語法
<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>

***陳述式***  
(必要) DynamoDB 專用 PartiQL 支援的陳述式。  
+ 整個批次必須由讀取陳述式或寫入陳述式所組成；一個批次中不能同時出現這兩種陳述式樣。
+ `BatchExecuteStatement` 和 `BatchWriteItem` 每個批次不可以執行超過 25 條陳述式。

***parametertype***  
(選用) DynamoDB 類型，如果在指定 PartiQL 陳述式時使用了參數。

***parametervalue***  
(選用) 參數值，如果在指定 PartiQL 陳述式時使用了參數。

## 範例
<a name="ql-reference.multiplestatements.batching.examples"></a>

------
#### [ AWS CLI ]

1. 將以下 json 儲存至名為 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. 在命令提示中執行下列命令。

   ```
   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());
        }
    }

}
```

------

# DynamoDB 專用 PartiQL 的 IAM 安全政策
<a name="ql-iam"></a>

需要以下許可：
+ 若要使用 DynamoDB 專用 PartiQL 讀取項目，您必須擁有資料表或索引的 `dynamodb:PartiQLSelect` 許可。
+ 若要使用 DynamoDB 專用 PartiQL 插入項目，您必須擁有資料表或索引的 `dynamodb:PartiQLInsert` 許可。
+ 若要使用 DynamoDB 專用 PartiQL 更新項目，您必須擁有資料表或索引的 `dynamodb:PartiQLUpdate` 許可。
+ 若要使用 DynamoDB 專用 PartiQL 刪除項目，您必須擁有資料表或索引的 `dynamodb:PartiQLDelete` 許可。

## 範例：允許在資料表上執行所有 DynamoDB 專用 PartiQL 陳述式 (選取/插入/更新/刪除)
<a name="access-policy-ql-iam-example1"></a>

下列 IAM 政策會授予許可，允許在資料表上執行所有 DynamoDB 專用 PartiQL 陳述式。

------
#### [ 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"
         ]
      }
   ]
}
```

------

## 範例：允許在資料表上執行 DynamoDB 專用 PartiQL 選取陳述式
<a name="access-policy-ql-iam-example2"></a>

下列 IAM 政策會授予許可，允許在特定資料表上執行 `select` 陳述式。

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ]
      }
   ]
}
```

------

## 範例：允許在索引上執行 DynamoDB 專用 PartiQL 插入陳述式
<a name="access-policy-ql-iam-example3"></a>

下列 IAM 政策會授予許可，允許在特定索引上執行 `insert` 陳述式。

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music/index/index1"
         ]
      }
   ]
}
```

------

## 範例：允許在資料表上僅執行 DynamoDB 專用 PartiQL 交易陳述式
<a name="access-policy-ql-iam-example4"></a>

下列 IAM 政策會授予許可，允許僅在特定資料表上執行交易陳述式。

------
#### [ 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"
               ]
            }
         }
      }
   ]
}
```

------

## 範例：允許在資料表上執行 DynamoDB 專用 PartiQL 非交易式讀取和寫入，並封鎖 PartiQL 交易式讀取和寫入交易陳述式。
<a name="access-policy-ql-iam-example5"></a>

 下列 IAM 政策會授予許可，允許執行 DynamoDB 專用 PartiQL 非交易式讀取和寫入，同時封鎖 DynamoDB 專用 PartiQL 交易式讀取和寫入。

------
#### [ 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"
         ]
      }
   ]
}
```

------

## 範例：允許在 DynamoDB 專用 PartiQL 中執行選取陳述式並拒絕完整的資料表掃描陳述式
<a name="access-policy-ql-iam-example6"></a>

下列 IAM 政策會授予許可，允許在特定資料表上執行 `select` 陳述式，同時封鎖會導致完整資料表掃描的 `select` 陳述式。

------
#### [ 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"
         ]
      }
   ]
}
```

------