

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

# AWS IoT SQL 參考
<a name="iot-sql-reference"></a>

在 中 AWS IoT，使用類似 SQL 的語法定義規則。SQL 陳述式是由三種類型的子句所組成：

**SET**  
（選用） 定義您可以在 SQL 陳述式和替代範本中重複使用的變數。使用表達式將值指派給變數。在 SELECT 和 WHERE 子句以及動作替代範本中參考這些變數。  
SET 子句支援 [資料類型](iot-sql-data-types.md)、[運算子](iot-sql-operators.md)、[函數](iot-sql-functions.md)、[文字](iot-sql-literals.md)、[案例陳述式](iot-sql-case.md)、[JSON Extensions](iot-sql-json.md)、[變數](iot-sql-set.md#iot-sql-set-usage)和 [巢狀物件查詢](iot-sql-nested-queries.md)。

**SELECT**  
(必要) 從傳入的訊息承載擷取資訊並對資訊執行轉換。要使用的訊息是由 FROM 子句中指定的[主題篩選條件](topics.md#topicfilters)所識別。  
SELECT 子句支援 [資料類型](iot-sql-data-types.md)、[運算子](iot-sql-operators.md)、[函數](iot-sql-functions.md)、[文字](iot-sql-literals.md)、[案例陳述式](iot-sql-case.md)[JSON Extensions](iot-sql-json.md)、[替代範本](iot-substitution-templates.md)、、[變數](iot-sql-set.md#iot-sql-set-usage)、 [巢狀物件查詢](iot-sql-nested-queries.md)和 [二進位承載](binary-payloads.md)。

**FROM**  
MQTT 訊息[主題篩選條件](topics.md#topicfilters)，可識別要從中擷取資料的訊息。系統會為每則傳送到符合此處指定的主題篩選條件之 MQTT 主題的訊息啟動該規則。對於透過訊息啟動的規則是必要的，而這些訊息是透過訊息代理程式傳遞的。若為僅使用[基本擷取](iot-basic-ingest.md)功能啟動的規則，則為選用。

**WHERE**  
(選用) 新增條件邏輯，其會判斷是否執行某規則指定的動作。  
WHERE 子句支援 [資料類型](iot-sql-data-types.md)、[運算子](iot-sql-operators.md)、[函數](iot-sql-functions.md)、[文字](iot-sql-literals.md)[案例陳述式](iot-sql-case.md)、、[JSON Extensions](iot-sql-json.md)、[變數](iot-sql-set.md#iot-sql-set-usage)和 [巢狀物件查詢](iot-sql-nested-queries.md)。

SQL 陳述式範例如下所示：

```
SELECT color AS rgb FROM 'topic/subtopic' WHERE temperature > 50
```

MQTT 訊息 (也稱作傳入承載) 的範例如下所示：

```
{
    "color":"red",
    "temperature":100
}
```

如果此訊息是發佈在 `'topic/subtopic'` 主題上，便會觸發規則，SQL 陳述式惠受到評估。如果 `color` 屬性大於 50，SQL 陳述式會擷取 `"temperature"` 屬性的值。WHERE 子句會指定條件 `temperature > 50`。`AS` 關鍵字將 `"color"` 屬性重新命名為 `"rgb"`。結果 (也稱作*傳出承載*) 會如以下所示：

```
{
    "rgb":"red"
}
```

該資料接下來會轉送給該規則的動作，並發送資料以進行更多處理作業。如需規則動作的詳細資訊，請參閱 [AWS IoT 規則動作](iot-rule-actions.md)。

**注意**  
 AWS IoT SQL 語法目前不支援註解。  
包含空格的屬性名稱不能用作 SQL 陳述式中的欄位名稱。雖然傳入的承載可以包含含有空格的屬性名稱，但這些名稱不能在 SQL 陳述式中使用。但是，如果您使用萬用字元 (\$1) 欄位名稱規範，這些名稱會被傳遞到傳出承載。

# SELECT 子句
<a name="iot-sql-select"></a>

 AWS IoT SELECT 子句基本上與 ANSI SQL SELECT 子句相同，但有一些細微差異。

SELECT 子句支援 [資料類型](iot-sql-data-types.md)、[運算子](iot-sql-operators.md)、[函數](iot-sql-functions.md)、[文字](iot-sql-literals.md)、[案例陳述式](iot-sql-case.md)[JSON Extensions](iot-sql-json.md)、、[變數](iot-sql-set.md#iot-sql-set-usage)、 [巢狀物件查詢](iot-sql-nested-queries.md)和 [二進位承載](binary-payloads.md)。

以使用 SELECT 子句來擷取傳入的 MQTT 訊息內的資訊。您也可以使用 `SELECT *` 來擷取整個傳入訊息的承載。例如：

```
Incoming payload published on topic 'topic/subtopic': {"color":"red", "temperature":50}
SQL statement: SELECT * FROM 'topic/subtopic'
Outgoing payload: {"color":"red", "temperature":50}
```

如果承載為 JSON 物件，您可以參考物件中的鍵。您的傳出承載會包含鍵值組。例如：

```
Incoming payload published on topic 'topic/subtopic': {"color":"red", "temperature":50}
SQL statement: SELECT color FROM 'topic/subtopic'
Outgoing payload: {"color":"red"}
```

您可以使用 AS 關鍵字重新命名索引鍵。例如：

```
Incoming payload published on topic 'topic/subtopic':{"color":"red", "temperature":50}
SQL:SELECT color AS my_color FROM 'topic/subtopic'
Outgoing payload: {"my_color":"red"}
```

您可以選擇多個項目，以逗號分隔即可。例如：

```
Incoming payload published on topic 'topic/subtopic': {"color":"red", "temperature":50}
SQL: SELECT color as my_color, temperature as fahrenheit FROM 'topic/subtopic'
Outgoing payload: {"my_color":"red","fahrenheit":50}
```

您可以選擇多個項目，包括以「\$1」新增項目至來年的承載。例如：

```
Incoming payload published on topic 'topic/subtopic': {"color":"red", "temperature":50}
SQL: SELECT *, 15 as speed FROM 'topic/subtopic'
Outgoing payload: {"color":"red", "temperature":50, "speed":15}
```

您可以使用 `"VALUE"` 關鍵字產生傳出的承載不 JSON 物件。使用 SQL 版本 `2015-10-08`，您只能選取一個項目。使用 SQL 版本 `2016-03-23` 或更新版本，您也可以選取要作為頂層物件輸出的陣列。

**Example**  

```
Incoming payload published on topic 'topic/subtopic': {"color":"red", "temperature":50}
SQL: SELECT VALUE color FROM 'topic/subtopic'
Outgoing payload: "red"
```

您可以使用 `'.'` 語法來深入巢狀 JSON 物件傳入的承載。例如：

```
Incoming payload published on topic 'topic/subtopic': {"color":{"red":255,"green":0,"blue":0}, "temperature":50}
SQL: SELECT color.red as red_value FROM 'topic/subtopic'
Outgoing payload: {"red_value":255}
```

如需如何使用 JSON 物件和包含保留字元 (例如數字或連字號 (減號) 字元) 之屬性名稱的相關資訊，請參閱 [JSON Extensions](iot-sql-json.md)

您可以使用函數 (請參閱 [函數](iot-sql-functions.md))，將傳入的承載。您可以使用括號進行分組。例如：

```
Incoming payload published on topic 'topic/subtopic': {"color":"red", "temperature":50}
SQL: SELECT (temperature - 32) * 5 / 9 AS celsius, upper(color) as my_color FROM 'topic/subtopic'
Outgoing payload: {"celsius":10,"my_color":"RED"}
```

# FROM 子句
<a name="iot-sql-from"></a>

FROM 子句可讓[主題](topics.md#topicnames)或[主題篩選條件](topics.md#topicfilters)訂閱您的規則。以單引號 (') 括住主題或主題篩選條件。系統會為每則傳送到符合此處指定的主題篩選條件之 MQTT 主題的訊息觸發該規則。您可以使用主題篩選條件訂閱類似主題的群組。

**範例**：

發佈在主題 `'topic/subtopic'` 的傳入承載：`{temperature: 50}`

發佈在主題 `'topic/subtopic-2'` 的傳入承載：`{temperature: 50}`

SQL：`"SELECT temperature AS t FROM 'topic/subtopic'"`。

規則已訂閱至 `'topic/subtopic'`，因此傳入的承載會傳遞至該規則。傳送至規則動作的外寄承載為：`{t: 50}`。規則並未給 `'topic/subtopic-2'` 訂閱，因此發佈在 `'topic/subtopic-2'` 的訊息不會觸發該規則。

**\$1 萬用字元範例：**

您可以使用 '\$1'(多層級) 萬用字元，以比對一或多個特定路徑元素：

發佈在主題 `'topic/subtopic'` 的傳入承載：`{temperature: 50}`。

發佈在主題 `'topic/subtopic-2'` 的傳入承載：`{temperature: 60}`。

發佈在主題 `'topic/subtopic-3/details'` 的傳入承載：`{temperature: 70}`。

發佈在主題 `'topic-2/subtopic-x'` 的傳入承載：`{temperature: 80}`。

SQL：`"SELECT temperature AS t FROM 'topic/#'"`。

已將該規則訂閱至開頭為 `'topic'` 的任何主題，因此該規則會執行三次，將傳出的 `{t: 50}` (表示主題/子主題)、`{t: 60}` (表示主題/子主題 2) 和 `{t: 70}` (表示主題/子主題 3/詳細資訊) 的承載傳送給其動作。它沒有訂閱 `'topic-2/subtopic-x'`，因此不會觸發 `{temperature: 80}` 訊息的規則。

**\$1 萬用字元範例：**

您可以使用 '\$1'(單層級) 萬用字元，以比對任何一個特定路徑元素：

發佈在主題 `'topic/subtopic'` 的傳入承載：`{temperature: 50}`。

發佈在主題 `'topic/subtopic-2'` 的傳入承載：`{temperature: 60}`。

發佈在主題 `'topic/subtopic-3/details'` 的傳入承載：`{temperature: 70}`。

發佈在主題 `'topic-2/subtopic-x'` 的傳入承載：`{temperature: 80}`。

SQL：`"SELECT temperature AS t FROM 'topic/+'"`。

所有主題訂閱的規則有兩個路徑元素，第一個為：`'topic'`。規則是針對傳送至 `'topic/subtopic'` 和 `'topic/subtopic-2'` 的訊息執行，但不是針對 `'topic/subtopic-3/details'` (它具有比主題過濾條件更多的層級) 或 `'topic-2/subtopic-x'` (它不是以 `topic` 開頭) 執行。

# SET 子句
<a name="iot-sql-set"></a>

使用 SET 子句來定義儲存表達式結果的變數。您可以在 SELECT 和 WHERE 子句以及替代範本中重複使用這些變數。這可協助您避免重複複雜的表達式，並減少 SQL 陳述式中的函數呼叫次數。

SET 子句支援 [資料類型](iot-sql-data-types.md)、[運算子](iot-sql-operators.md)、[函數](iot-sql-functions.md)、[文字](iot-sql-literals.md)、[案例陳述式](iot-sql-case.md)、[JSON Extensions](iot-sql-json.md)、[變數](#iot-sql-set-usage)和 [巢狀物件查詢](iot-sql-nested-queries.md)。

## SET 子句語法
<a name="iot-sql-set-syntax"></a>

SET 子句必須出現在 SQL 陳述式中的 SELECT 子句前面。使用下列語法：

```
SET @variable_name = expression [, @variable_name2 = expression2]
```

語法規則：
+ 使用 啟動變數名稱 `@`
+ 變數名稱可以包含字母、數字和底線
+ 變數名稱長度最多可達 64 個字元
+ 您可以在單一 SET 子句中設定多個變數，並以逗號分隔
+ 每個變數只能指派一次 （變數不可變）
+ 每個 SQL 陳述式只能使用一次 SET 關鍵字

## 使用變數
<a name="iot-sql-set-usage"></a>

定義變數之後，您可以在以下位置使用它們：
+ SELECT 子句
+ WHERE 子句
+ 其他 SET 變數指派
+ 動作替換範本
+ 錯誤動作替換範本
+ 巢狀 SELECT 查詢
+ 函數參數 （某些參數，例如 roleArn 參數，以及切換類似`transform("enrichArray", attributes, values)`不支援變數之函數模式的參數）

變數會使用與 SET `@variable_name` 子句相同的語法來參考。您也可以使用 JSON 延伸語法來存取包含 物件之變數的屬性，例如 `@variable_name.property`。

## SET 子句範例
<a name="iot-sql-set-examples"></a>

**基本變數用量**

下列範例顯示發佈在主題 上的承載`device/data`： `{"temp_fahrenheit": 75, "humidity": 60}`

SQL 陳述式：

```
SET @temp_celsius = (temp_fahrenheit - 32) * 5 / 9
SELECT @temp_celsius AS celsius, humidity FROM 'device/data'
```

傳出承載： `{"celsius": 23.89, "humidity": 60}`

**存取內嵌 JSON 物件中的成員 **

下列範例顯示發佈在主題 上的承載`device/data`： `{"device1": {"deviceId":"weather_sensor", "deviceData": {"sensors": {"temp_fahrenheit": 75, "humidity": 60}, "location": [47.606,-122.332]}}}`

SQL 陳述式：

```
SET @device_sensor_data = device1.deviceData.sensors
SELECT @device_sensor_data.temp_fahrenheit AS temp_fahrenheit, @device_sensor_data.humidity as humidity, device1.deviceId as deviceId FROM 'device/data'
```

傳出承載： `{"temp_fahrenheit":75,"humidity":60,"deviceId":"weather_sensor"}`

 如需如何使用 JSON 延伸模組的詳細資訊，請參閱 [JSON Extensions](iot-sql-json.md) 

**避免重複的函數呼叫**

SET 變數有助於避免重複複雜的解碼操作：

```
SET @decoded_data = decode(encode(*, 'base64'), 'proto', 'schema', 'schema.desc', 'message.proto', 'Message')
SELECT @decoded_data.sensor_id, @decoded_data.reading FROM 'device/protobuf' 
WHERE @decoded_data.reading > 100
```

如果沒有 SET 變數，您需要重複三次解碼函數，這超過函數呼叫限制。

**多個變數**

您可以在單一 SET 子句中定義多個變數，方法是使用逗號分隔它們：

```
SET @user_data = get_user_properties(device_id), @threshold = 50
SELECT @user_data.name, temp_fahrenheit FROM 'sensors/+'
WHERE temp_fahrenheit > @threshold AND @user_data.active = true
```

**在替代範本中使用變數**

變數也可以用於動作替換範本，讓您可以在 SQL 陳述式和規則動作之間重複使用運算值。

SQL 陳述式：

```
SET @temp_celsius = (temp_fahrenheit - 32) * 5 / 9
SELECT @temp_celsius AS celsius, humidity FROM 'device/data'
```

動作組態：

```
{
  "s3": {
    "roleArn": "arn:aws:iam::123456789012:role/testRuleRole",
    "bucketName": "bucket",
    "key": "temperature-data/${device_id}/temp-${@temp_celsius}C.json"
  }
}
```

在此範例中，SET 變數`@temp_celsius`用於替代範本中，以建構 S3 動作的金鑰欄位。

**非 JSON 承載用量**

SET 變數不支援直接支援非 JSON 承載，因此必須先對承載進行編碼或解碼：

```
SET @encoded_payload = encode(*, 'base64')
SELECT @encoded_payload AS raw_data FROM 'device/binary'
```

 如需如何使用非 JSON 承載的詳細資訊，請參閱 [使用二進位承載](binary-payloads.md) 

## SET 子句限制
<a name="iot-sql-set-limits"></a>

下列限制適用於 SET 變數：
+ 每個 SQL 陳述式最多 10 個唯一變數
+ 最大變數值大小為 128 KiB （最小 UTF-8 JSON 字串）
+ 所有變數的總值大小上限為 128 KiB 
+ 變數名稱限制為 64 個字元
+ 變數可以直接接受 JSON 承載 （必須先編碼/解碼非 JSON 承載）

# WHERE 子句
<a name="iot-sql-where"></a>

WHERE 子句會判斷是否執行某規則指定的動作。如果 WHERE 子句判斷值為 true，則規則動作已執行。否則，規則動作就不會執行。

WHERE 子句支援 [資料類型](iot-sql-data-types.md)、[運算子](iot-sql-operators.md)、[函數](iot-sql-functions.md)、[文字](iot-sql-literals.md)、[案例陳述式](iot-sql-case.md)、[JSON Extensions](iot-sql-json.md)、[變數](iot-sql-set.md#iot-sql-set-usage)和 [巢狀物件查詢](iot-sql-nested-queries.md)。

**範例**：

發佈在 `topic/subtopic` 的傳入承載：`{"color":"red", "temperature":40}`。

SQL：`SELECT color AS my_color FROM 'topic/subtopic' WHERE temperature > 50 AND color <> 'red'`。

在此情況下，該規則會觸發，但不會執行由規則指定的動作。將不會出現傳出承載。

您可以在 WHERE 子句中使用函數和運算子。不過您無法參考任何在 SELECT 中以 AS 關鍵字建立的別名。(系統會優先評估 WHERE 子句，以判定 SELECT 是否受到評估。) 

**非 JSON 承載的範例：**

在「主題/副主題」上發佈的傳入非 JSON 承載：`80`

SQL:``SELECT decode(encode(*, 'base64'), 'base64') AS value FROM 'topic/subtopic' WHERE decode(encode(*, 'base64'), 'base64') > 50`

在此情況下，該規則會觸發，並且執行由規則指定的動作。傳出承載將由 SELECT 子句轉換為 JSON 承載 `{"value":80}`。

# 資料類型
<a name="iot-sql-data-types"></a>

 AWS IoT 規則引擎支援所有 JSON 資料類型。


**支援的資料類型**  

| Type | 意義 | 
| --- | --- | 
| Int | 離散的 Int。最多 34 位數。 | 
| Decimal |  精度為 34 位的 `Decimal`，最小非零量級為 1E-999，最大量級為 9.999…E999。  有些函數傳回的 `Decimal` 值為雙精度，而非 34 位數的精度。 使用 SQL V2 (2016-03-23) 時，數值若為整數 (例如 `10.0`) 會被當成 `Int` 值 (`10`) 處理，而不是預期的 `Decimal` 值 (`10.0`)。若要可靠地將整數數值當成 `Decimal` 值處理，請針對規則查詢陳述式使用 SQL V1 (2015-10-08)。   | 
| Boolean | True 或 False | 
| String | UTF-8 字串。 | 
| Array | 一系列類型無需相同的值。 | 
| Object | 由鍵和值組成的 JSON 值。鍵必須為字串。值可以為任何類型。 | 
| Null | Null 是由 JSON 定義。此為用來代表缺少某個值的實際值。您可以在 SQL 陳述式中使用 Null 的關鍵字來明確建立 Null 的值。例如："SELECT NULL AS n FROM 'topic/subtopic'" | 
| Undefined |  並非值。無法以 JSON 明確顯示，除非是省略該值。舉例而言，在物件 `{"foo": null}` 中，「foo」鍵會傳回 NULL，但「bar」鍵傳回 `Undefined`。SQL 語言在內部將 `Undefined` 視為一個值，但無法以 JSON 顯示，因此序列化為 JSON 時，結果會是 `Undefined`。 <pre> {"foo":null, "bar":undefined} </pre> 序列化為 JSON 如下： <pre> {"foo":null}</pre> 同樣地，`Undefined` 由自身序列化時，會轉換為空白字串。以無效引數 (例如，錯誤類型、錯誤的引數數量等等) 呼叫的函數會傳回 `Undefined`。  | 

## 轉換
<a name="iot-sql-conversions"></a>

下表列出的是當某個類型的值轉換為另一種類型 (給函數指定錯誤類型的值) 所得的結果。舉例而言，如果絕對值的函數「abs」(預期為 `Int`或 `Decimal`) 得到的是 `String`，其會嘗試按照下列規則將 `String` 轉換為 `Decimal`。此例中，'abs("-5.123")' 會視為 'abs(-5.123)'。

**注意**  
不會企圖轉換為 `Array`、`Object`、`Null`、`Undefined`。


**To Decimal**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | 無小數點的 Decimal。 | 
| Decimal | 來源值。 | 
| Boolean | Undefined。(您可以明確使用 Cast 函數轉換 true = 1.0、false = 0.0。) | 
| String | SQL 引擎會嘗試將字串剖析為 Decimal. AWS IoT attempts，以剖析符合規則表達式的字串：^-?\$1d\$1(\$1.\$1d\$1)?((?i)E-?\$1d\$1)?\$1。「0」、「-1.2」、「5E-12」均為自動轉換為 Decimal 的範例字串。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Null. | 
| 未定義 | Undefined. | 


**To Int**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | 來源值。 | 
| Decimal | 四捨五入到最接近 Int 的來源值。 | 
| Boolean | Undefined。(您可以明確使用 Cast 函數轉換 true = 1.0、false = 0.0。) | 
| String |  SQL 引擎會嘗試將字串剖析為 Decimal. AWS IoT attempts，以剖析符合規則表達式的字串：^-?\$1d\$1(\$1.\$1d\$1)?((?i)E-?\$1d\$1)?\$1。"0"、"-1.2"、"5E-12" 是字串的所有範例，這些字串會自動轉換為 Decimals. AWS IoT attempts，以String將 轉換為 Decimal，然後截斷該字串的小數位Decimal數以製作 Int。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Null. | 
| 未定義 | Undefined. | 


**To Boolean**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Undefined。(您可以明確使用 cast 函數轉換 0 = False、any\$1nonzero\$1value = True。) | 
| Decimal | Undefined。(您可以明確使用 Cast 函數轉換 0 = False、any\$1nonzero\$1value = True。) | 
| Boolean | 原始的值。 | 
| String | 「true」= True 而「false」= False (不區分大小寫)。其他字串值為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 


**To String**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | 以標準表示法表示的 Int 的字串顯示方式。 | 
| Decimal | 代表 Decimal 值的字串，可能是採取科學表示法。 | 
| Boolean | 「true」或「false」。所有小寫。 | 
| String | 原始的值。 | 
| 陣列 | 序列化為 JSON 的 Array。該結果字串為以逗號分隔的清單，並包含在方括弧內。String 在括號中。Decimal、Int、Boolean 和 Null 則不是。 | 
| 物件 | 序列化為 JSON 的物件。該結果字串為以逗號分隔的鍵值組清單，並以大括號為開頭和結尾。String 在括號中。Decimal、Int、Boolean 和 Null 則不是。 | 
| Null | Undefined. | 
| 未定義 | 未定義。 | 

# 運算子
<a name="iot-sql-operators"></a>

下列運算子可用於 SELECT 和 WHERE 子句。

## AND 運算子
<a name="iot-sql-operators-and"></a>

傳回 `Boolean` 結果。執行邏輯 AND 運算。如果左右運算元為 true，即傳回 true。否則會傳回 false。需要 `Boolean` 運算元或不區分大小寫的「true」或「false」字串運算元。

*語法：*` expression AND expression`。


**AND 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Boolean | Boolean | Boolean。如果兩個運算元皆為 true 即為 true。否則為 false。 | 
| String/Boolean | String/Boolean | 如果所有字串均為「true」或「false」(不區分大小寫)，他們會轉換為 Boolean，並以 boolean AND boolean 的方式正常處理。 | 
| 其他值 | 其他值 | Undefined. | 

## OR 運算子
<a name="iot-sql-operators-or"></a>

傳回 `Boolean` 結果。執行邏輯 OR 運算。如果右運算元或左運算元有一個為 true 即傳回 true。否則會傳回 false。需要 `Boolean` 運算元或不區分大小寫的「true」或「false」字串運算元。

*語法：*` expression OR expression`。


**OR 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Boolean | Boolean | Boolean。如果有一個運算元為 true 即為 true。否則為 false。 | 
| String/Boolean | String/Boolean | 如果所有字串均為「true」或「false」(不區分大小寫)，它們會轉換為布林值，並以 boolean OR boolean 的方式正常處理。 | 
| 其他值 | 其他值 | Undefined. | 

## NOT 運算子
<a name="iot-sql-operators-not"></a>

傳回 `Boolean` 結果。執行邏輯 NOT 運算。如果運算元為 false 即傳回 true。否則即傳回 true。需要 `Boolean` 運算元或不區分大寫的「true」或「false」字串運算元。

*語法：*`NOT expression`。


**NOT 運算子**  

| 運算元 | Output | 
| --- | --- | 
| Boolean | Boolean。如果運算元為 false 即為 true。否則為 true。 | 
| String | 如果字串為「true」或「false」(不區分大小寫)，則會轉換為對應的布林值，並傳回相反的值。 | 
| 其他值 | Undefined. | 

## IN 運算子
<a name="iot-sql-operators-in"></a>

傳回 `Boolean` 結果。您可以使用 WHERE 子句中的 IN 運算子來檢查值是否符合陣列中的任何值。如果找到相符項目，則傳回 true，否則傳回 false。

*語法：*` expression IN expression`。


**IN 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int/Decimal/String/Array/Object | Array | 如果在陣列中找到 Integer/Decimal/String/Array/ Object元素，則為 True。否則為 false。 | 

*範例*：

```
SQL: "select * from 'a/b' where 3 in arr"

JSON: {"arr":[1, 2, 3, "three", 5.7, null]}
```

在此範例中，條件子句`where 3 in arr`將評估為 true，因為 3 存在於名為 的陣列中`arr`。因此，在 SQL 陳述式中， `select * from 'a/b'`將執行。此範例也會顯示陣列可以是異質的。

## EXISTS 運算子
<a name="iot-sql-operators-exists"></a>

傳回 `Boolean` 結果。您可以在條件式子句中使用 EXISTS 運算子來測試子查詢中是否存在元素。如果子查詢傳回一或多個元素，則傳回 true；如果子查詢未傳回元素，則傳回 false。

*語法：*` expression`。

*範例*：

```
SQL: "select * from 'a/b' where exists (select * from arr as a where a = 3)"

JSON: {"arr":[1, 2, 3]}
```

在此範例中，條件子句`where exists (select * from arr as a where a = 3)`將評估為 true，因為 3 存在於名為 的陣列中`arr`。因此，在 SQL 陳述式中， `select * from 'a/b'`將執行。

*範例*：

```
SQL: select * from 'a/b' where exists (select * from e as e where foo = 2)

JSON: {"foo":4,"bar":5,"e":[{"foo":1},{"foo":2}]}
```

在此範例中，條件子句`where exists (select * from e as e where foo = 2)`將評估為 true，因為 JSON 物件`e`內的陣列包含物件 `{"foo":2}`。因此，在 SQL 陳述式中， `select * from 'a/b'`將執行。

## > 運算子
<a name="iot-sql-operators-greater"></a>

傳回 `Boolean` 結果。如果左運算元大於右運算元即傳回 true。兩個運算元均轉換為 `Decimal`，再做比較。

*語法：*`expression > expression`。


**> 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int/Decimal | Int/Decimal | Boolean。如果左運算元大於右運算元即為 true。否則為 false。 | 
| String/Int/Decimal | String/Int/Decimal | 如果所有字串均可轉換為 Decimal，即 Boolean。如果左運算元大於右運算元即傳回 true。否則為 false。 | 
| 其他值 | Undefined. | Undefined. | 

## >= 運算子
<a name="iot-sql-operators-greater-equal"></a>

傳回 `Boolean` 結果。如果左運算元大於或等於右運算元，即傳回 true。兩個運算元均轉換為 `Decimal`，再做比較。

*語法：*`expression >= expression`。


**>= 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int/Decimal | Int/Decimal | Boolean。如果左運算元大於或等於右運算元，即為 true。否則為 false。 | 
| String/Int/Decimal | String/Int/Decimal | 如果所有字串均可轉換為 Decimal，即 Boolean。如果左運算元大於或等於右運算元，即傳回 true。否則為 false。 | 
| 其他值 | Undefined. | Undefined. | 

## < 運算子
<a name="iot-sql-operators-less"></a>

傳回 `Boolean` 結果。如果左側運算元少於右運算元。兩個運算元均轉換為 `Decimal`，再做比較。

*語法：*`expression < expression`。


**< 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int/Decimal | Int/Decimal | Boolean。如果左運算元小於右運算元即為 true。否則為 false。 | 
| String/Int/Decimal | String/Int/Decimal | 如果所有字串均可轉換為 Decimal，即 Boolean。如果左側運算元少於右運算元。否則為 false。 | 
| 其他值 | Undefined | Undefined | 

## <= 運算子
<a name="iot-sql-operators-less-equal"></a>

傳回 `Boolean` 結果。如果左運算元小於或等於右運算元，即傳回 true。兩個運算元均轉換為 `Decimal`，再做比較。

*語法：*`expression <= expression`。


**<= 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int/Decimal | Int/Decimal | Boolean。如果左運算元小於或等於右運算元，即為 true。否則為 false。 | 
| String/Int/Decimal | String/Int/Decimal | 如果所有字串均可轉換為 Decimal，即 Boolean。如果左運算元小於或等於右運算元，即傳回 true。否則為 false。 | 
| 其他值 | Undefined | Undefined | 

## <> 運算子
<a name="iot-sql-operators-not-eq"></a>

傳回 `Boolean` 結果。如果左右運算元不相等，即傳回 true。否則即傳回 false。

*語法：*` expression <> expression`。


**<> 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int | Int | 如果左運算元不等於右運算元即為 true。否則為 false。 | 
| Decimal | Decimal | 如果左運算元不等於右運算元即為 true。否則為 false。在做比較前，先將 Int 轉換為 Decimal。 | 
| String | String | 如果左運算元不等於右運算元即為 true。否則為 false。 | 
| 陣列 | 陣列 | 如果各運算元的項目不相等且順序不同，即為 true。否則為 false | 
| 物件 | 物件 | 如果各運算元的鍵和值不相同，即為 true。否則為 false。鍵/值的順序不重要。 | 
| Null | Null | False。 | 
| 任何值 | Undefined | 未定義。 | 
| Undefined | 任何值 | 未定義。 | 
| 類型不符合 | 類型不符合 | True。 | 

## = 運算子
<a name="iot-sql-operators-eq"></a>

傳回 `Boolean` 結果。如果兩個左右運算元相同，即傳回 true。否則即傳回 false。

*語法：*` expression = expression`。


**= 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int | Int | 如果左運算元等於右運算元即為 true。否則為 false。 | 
| Decimal | Decimal | 如果左運算元等於右運算元即為 true。否則為 false。在做比較前，先將 Int 轉換為 Decimal。 | 
| String | String | 如果左運算元等於右運算元即為 true。否則為 false。 | 
| 陣列 | 陣列 | 如果各運算元的項目相等且順序相同，即為 true。否則為 false。 | 
| 物件 | 物件 | 如果各運算元的鍵和值相同，即為 true。否則為 false。鍵/值的順序不重要。 | 
| 任何值 | Undefined | Undefined. | 
| Undefined | 任何值 | Undefined. | 
| 類型不符合 | 類型不符合 | False。 | 

## \$1 運算子
<a name="iot-sql-operators-plus"></a>

「\$1」是過載的運算子。可以用來連接或新增字串。

*語法：*` expression + expression`。


**\$1 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| String | 任何值 | 將右運算元轉換為字串，並連接至左運算元的尾端。 | 
| 任何值 | String | 將左運算元轉換為字串，並將右運算元連接至轉換後的左運算元的尾端。 | 
| Int | Int | Int 值。將運算元相加。 | 
| Int/Decimal | Int/Decimal | Decimal 值。將運算元相加。 | 
| 其他值 | 其他值 | Undefined. | 

## - 運算子
<a name="iot-sql-operators-sub"></a>

從左運算元中減去右運算元。

*語法：*` expression - expression`。


**- 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int | Int | Int 值。從左運算元中減去右運算元。 | 
| Int/Decimal | Int/Decimal | Decimal 值。從左運算元中減去右運算元。 | 
| String/Int/Decimal | String/Int/Decimal | 如果所有字串都正確轉換為小數，則會傳回 Decimal 值。從左運算元中減去右運算元。如果不是，則傳回 Undefined。 | 
| 其他值 | 其他值 | Undefined. | 
| 其他值 | 其他值 | Undefined. | 

## \$1 運算子
<a name="iot-sql-operators-mult"></a>

將左運算元乘以右運算元。

*語法：*` expression * expression`。


**\$1 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int | Int | Int 值。將左運算元乘以右運算元。 | 
| Int/Decimal | Int/Decimal | Decimal 值。將左運算元乘以右運算元。 | 
| String/Int/Decimal | String/Int/Decimal | 如果所有字串都正確轉換為小數，則會傳回 Decimal 值。將左運算元乘以右運算元。如果不是，則傳回 Undefined。 | 
| 其他值 | 其他值 | Undefined. | 

## / 運算子
<a name="iot-sql-operators-div"></a>

將左運算元除以右運算元。

*語法：*` expression / expression`。


**/ 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int | Int | Int 值。將左運算元除以右運算元。 | 
| Int/Decimal | Int/Decimal | Decimal 值。將左運算元除以右運算元。 | 
| String/Int/Decimal | String/Int/Decimal | 如果所有字串都正確轉換為小數，則會傳回 Decimal 值。將左運算元除以右運算元。如果不是，則傳回 Undefined。 | 
| 其他值 | 其他值 | Undefined. | 

## % 運算子
<a name="iot-sql-operators-mod"></a>

傳回左運算元除以右運算元的餘數。

*語法：*` expression % expression`。


**% 運算子**  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int | Int | Int 值。傳回左運算元除以右運算元的餘數。 | 
| String/Int/Decimal | String/Int/Decimal | 如果所有字串都正確轉換為小數，則會傳回 Decimal 值。傳回左運算元除以右運算元的餘數。否則為 Undefined。 | 
| 其他值 | 其他值 | Undefined. | 

# 函數
<a name="iot-sql-functions"></a>

您可以在 SQL 表達式的 SELECT 或 WHERE 子句中使用下列內建函數。

下列外部函數的計費方式等同於規則動作的計費方式：[https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-func-aws-lambda](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-func-aws-lambda)、[https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-registry_data](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-registry_data)、 [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-dynamodb](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-dynamodb)和 [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-thing-shadow](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-thing-shadow)。只有在您將 [Protobuf 訊息解碼至 JSON](https://docs.aws.amazon.com//iot/latest/developerguide/binary-payloads.html#binary-payloads-protobuf) 時，您才會收到[https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-decode-base64](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-decode-base64)函數的帳單。如需詳細資訊，請參閱 [AWS IoT Core 定價頁面](https://aws.amazon.com/iot-core/pricing/)。

## abs(Decimal)
<a name="iot-func-abs"></a>

傳回某個數字的絕對值。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`abs(-5)` 傳回 5。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Int，引數的絕對值。 | 
| Decimal | Decimal，引數的絕對值。 | 
| Boolean | Undefined. | 
| String | Decimal。結果為引數的絕對值。如果字串無法轉換，則結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## accountid()
<a name="iot-sql-function-accountid"></a>

將擁有此規則的帳戶 ID 傳回為 `String`。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`accountid() ` = "123456789012"

## acos(Decimal)
<a name="iot-func-acos"></a>

以弧度傳回數字的反餘弦值。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`acos(0)` = 1.5707963267948966 


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，引數的反向餘弦值。傳回的虛數結果為 Undefined。 | 
| Decimal | Decimal (使用雙精度)，引數的反向餘弦值。傳回的虛數結果為 Undefined。 | 
| Boolean | Undefined. | 
| String | Decimal，引數的反向餘弦值。如果字串無法轉換，則結果為 Undefined。傳回的虛數結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## asin(Decimal)
<a name="iot-func-asin"></a>

以弧度傳回數字的反正弦值。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`asin(0)` = 0.0


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，引數的反向正弦值。傳回的虛數結果為 Undefined。 | 
| Decimal | Decimal (使用雙精度)，引數的反向正弦值。傳回的虛數結果為 Undefined。 | 
| Boolean | Undefined. | 
| String | Decimal (使用雙精度)，引數的反向正弦值。如果字串無法轉換，則結果為 Undefined。傳回的虛數結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## atan(Decimal)
<a name="iot-func-atan"></a>

以弧度傳回數字的反正切值。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`atan(0)` = 0.0


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，引數的反向正切值。傳回的虛數結果為 Undefined。 | 
| Decimal | Decimal (使用雙精度)，引數的反向正切值。傳回的虛數結果為 Undefined。 | 
| Boolean | Undefined. | 
| String | Decimal，引數的反向正切值。如果字串無法轉換，則結果為 Undefined。傳回的虛數結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## atan2(Decimal, Decimal)
<a name="iot-func-atan2"></a>

以弧度傳回 x 軸正軸和兩個引數所定義的 (x, y) 點之間的角度。 逆時針角度為正值 (上半象限，y > 0)，順時鐘的角度為負值 (下半象限 y < 0)。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`atan2(1, 0)` = 1.5707963267948966


****  

| 引數類型 | 引數類型 | 結果 | 
| --- | --- | --- | 
| Int/Decimal | Int/Decimal | Decimal (使用雙精度)，x 軸與指定的 (x, y) 點之間的角度。 | 
| Int/Decimal/String | Int/Decimal/String | Decimal，所述之點的反向正切值。如果字串無法轉換，則結果為 Undefined。 | 
| 其他值 | 其他值 | Undefined. | 

## aws\$1lambda (functionArn、inputJson)
<a name="iot-func-aws-lambda"></a>

 呼叫指定的 Lambda 函數，其會將 `inputJson` 傳送至 Lambda 函數，並傳回 Lambda 函數產生的 JSON。


**引數**  

| 引數 | Description | 
| --- | --- | 
| functionArn |  Lambda 函數呼叫的 ARN。Lambda 函數必須傳回 JSON 資料。  | 
| inputJson |  傳遞到 Lambda 函數的 JSON 輸入。若要傳遞巢狀物件查詢和文字，您必須使用 SQL 版本 2016-03-23。  | 

您必須授予 AWS IoT `lambda:InvokeFunction`叫用指定 Lambda 函數的許可。下列範例顯示了如何使用 AWS CLI授與 `lambda:InvokeFunction` 的許可：

```
aws lambda add-permission --function-name "function_name"
--region "region"
--principal iot.amazonaws.com 
--source-arn arn:aws:iot:us-east-1:account_id:rule/rule_name
--source-account "account_id"
--statement-id "unique_id" 
--action "lambda:InvokeFunction"
```

以下為 **add-permission** 命令的引數：

--function-name   
Lambda 函數的名稱。您可以新增許可來更新函數的資源政策。

--region  
您帳戶的 AWS 區域 。

--principal  
取得許可的委託人。這應該`iot.amazonaws.com`允許呼叫 Lambda 函數的 AWS IoT 許可。

--source-arn  
該項規則的 ARN。您可以使用 **get-topic-rule** AWS CLI 命令來取得規則的 ARN。

--source-account  
定義規則 AWS 帳戶 的 。

--statement-id  
專屬的陳述式識別符。

--action  
您想要在此陳述式中允許的 Lambda 動作。若要允許 AWS IoT 叫用 Lambda 函數，請指定 `lambda:InvokeFunction`。

**重要**  
如果您在未提供 `source-arn`或 的情況下新增 AWS IoT 委託人的許可`source-account`，任何 AWS 帳戶 使用 Lambda 動作建立規則的 都可以觸發規則來叫用您的 Lambda 函數 AWS IoT。如需詳細資訊，請參閱 [Lambda 許可模型](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html)。

指定的 JSON 訊息承載，如以下所示：

```
{
    "attribute1": 21,
    "attribute2": "value"
}
```

`aws_lambda` 函數可用於呼叫 Lambda 函數，如下所示：

```
SELECT
aws_lambda("arn:aws:lambda:us-east-1:account_id:function:lambda_function", {"payload":attribute1}) as output FROM 'topic-filter'
```

如果您想要傳遞完整的 MQTT 訊息承載，您可以使用「\$1」來指定 JSON 承載，如下列範例所示。

```
SELECT
aws_lambda("arn:aws:lambda:us-east-1:account_id:function:lambda_function", *) as output FROM 'topic-filter'
```

`payload.inner.element` 會從發佈在「主題/子主題」主題上的訊息選取資料。

`some.value` 會從 Lambda 函數產生的輸出結果中選取資料。

**注意**  
 該規則引擎會限制 Lambda 函數的執行期間。規則的 Lambda 函數呼叫應該會在 2000 毫秒內完成。

## bitand (Int、Int)
<a name="iot-func-bitand"></a>

在兩個 `Int` (已轉換) 引數的位元表現上執行按位元的 AND 運算。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`bitand(13, 5)` = 5


****  

| 引數類型 | 引數類型 | 結果 | 
| --- | --- | --- | 
| Int | Int | Int，兩個引數按位元的 AND 運算。 | 
| Int/Decimal | Int/Decimal | Int，兩個引數按位元的 AND 運算。所有非 Int 的數字會無條件捨去至最接近的 Int。如果任何引數無法轉換至 Int，結果會為 Undefined。 | 
| Int/Decimal/String | Int/Decimal/String | Int，兩個引數按位元的 AND 運算。所有字串都會轉換為小數，並會無條件捨去至最接近的 Int (整數)。如果轉換失敗，則結果為 Undefined。 | 
| 其他值 | 其他值 | Undefined. | 

## bitor(Int, Int)
<a name="iot-func-bitor"></a>

在兩個引數的位元表現上執行按位元的 OR 運算。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`bitor(8, 5)` = 13


****  

| 引數類型 | 引數類型 | 結果 | 
| --- | --- | --- | 
| Int | Int | Int，兩個引數按位元的 OR 運算。 | 
| Int/Decimal | Int/Decimal | Int，兩個引數按位元的 OR 運算。所有非 Int 的數字會無條件捨去至最接近的 Int。如果轉換失敗，則結果為 Undefined。 | 
| Int/Decimal/String | Int/Decimal/String | Int，兩個引數按位元的 OR 運算。所有字串都會轉換為小數，並會無條件捨去至最接近的 Int (整數)。如果轉換失敗，則結果為 Undefined。 | 
| 其他值 | 其他值 | Undefined. | 

## bitxor(Int, Int)
<a name="iot-func-xbitor"></a>

在兩個 `Int` (已轉換) 引數的位元表現上執行按位元的 XOR 運算。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`bitor(13, 5)` = 8


****  

| 引數類型 | 引數類型 | 結果 | 
| --- | --- | --- | 
| Int | Int | Int，兩個引數按位元的 XOR 運算。 | 
| Int/Decimal | Int/Decimal | Int，兩個引數按位元的 XOR 運算。非 Int 的數字會無條件捨去至最接近的 Int。 | 
| Int/Decimal/String | Int/Decimal/String | Int 是在兩個引數上的位元 XOR。字串會轉換為小數，並無條件捨去至最接近的 Int。如果任何轉換失敗，則結果為 Undefined。 | 
| 其他值 | 其他值 | Undefined. | 

## bitnot(Int)
<a name="iot-func-bitnot"></a>

在 `Int` (已轉換) 引數的位元表現上執行按位元的 NOT 運算。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`bitnot(13)` = 2


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Int，引數按位元的 NOT 運算。 | 
| Decimal | Int，引數按位元的 NOT 運算。Decimal值會無條件捨去至最接近 Int 的值。 | 
| String | Int，引數按位元的 NOT 運算。字串會轉換為小數，並會無條件捨去至最接近的 Int (整數)。如果任何轉換失敗，則結果為 Undefined。 | 
| 其他值 | 其他值。 | 

## cast()
<a name="iot-sql-function-cast"></a>

將一個值從某個資料類型轉換至另一個類型。除了增加了將數字和布林值相互轉換的能力外，轉換行為大致如同標準轉換。如果 AWS IoT 無法判斷如何將一種類型轉換為另一種類型，則結果為 `Undefined`。受 SQL 版本 2015-10-08 和更新版本支援。格式：cast (*value* as *type*)。

範例：

`cast(true as Int) ` = 1

在呼叫 `cast` 時，以下關鍵字可能出現在「as」之後：


**對於 SQL 版本 2015-10-08 與 2016-03-23**  

| 關鍵字 | 結果 | 
| --- | --- | 
| String | 將值轉換為 String。 | 
| Nvarchar | 將值轉換為 String。 | 
| 文字 | 將值轉換為 String。 | 
| Ntext | 將值轉換為 String。 | 
| varchar | 將值轉換為 String。 | 
| Int | 將值轉換為 Int。 | 
| Integer | 將值轉換為 Int。 | 
| Double | 將值轉換為 Decimal (使用雙精度)。 | 


**此外，對於 SQL 版本 2016-03-23**  

| 關鍵字 | 結果 | 
| --- | --- | 
| Decimal | 將值轉換為 Decimal。 | 
| Bool | 將值轉換為 Boolean。 | 
| Boolean | 將值轉換為 Boolean。 | 

轉換規則：


**轉換為小數**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | 無小數點的 Decimal。 | 
| Decimal |  來源值。  使用 SQL V2 (2016-03-23) 時，數值若為整數 (例如 `10.0`) 會傳回 `Int` 值 (`10`)，而不是預期的 `Decimal` 值 (`10.0`)。若要可靠地將整數數值當成 `Decimal` 值處理，請針對規則查詢陳述式使用 SQL V1 (2015-10-08)。   | 
| Boolean | true = 1.0、false = 0.0。 | 
| String | 嘗試將字串剖析為 Decimal。 AWS IoT 會嘗試剖析字串以符合正規表示式：^-?\$1d\$1(\$1.\$1d\$1)?((?i)E-?\$1d\$1)?\$1。「0」、「-1.2」、「5E-12」均為自動轉換為 Decimal 的範例字串。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 


**轉換為 Int**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | 來源值。 | 
| Decimal | 無條件捨去至最接近 Int 的來源值。 | 
| Boolean | true = 1.0、false = 0.0。 | 
| String | 嘗試將字串剖析為 Decimal。 AWS IoT 會嘗試剖析字串以符合正規表示式：^-?\$1d\$1(\$1.\$1d\$1)?((?i)E-?\$1d\$1)?\$1。「0」、「-1.2」、「5E-12」均為自動轉換為 Decimal 的範例字串。 AWS IoT 會嘗試將字串轉換為 Decimal，並無條件捨去至最接近的 Int。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 


**轉換到 `Boolean`**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | 0 = False，any\$1nonzero\$1value = True。 | 
| Decimal | 0 = False，any\$1nonzero\$1value = True。 | 
| Boolean | 來源值。 | 
| String | 「true」= True 而「false」= False (不區分大小寫)。其他字串值 = Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 


**轉換為字串**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | 以標準表示法表示的 Int 的字串顯示方式。 | 
| Decimal | 代表 Decimal 值的字串，可能是採取科學表示法。 | 
| Boolean | 「true」或「false」，均為小寫。 | 
| String | 來源值。 | 
| 陣列 | 序列化為 JSON 的陣列。結果字串是以方括號括住，並以逗號分隔的清單。String 在括號中。Decimal、Int 和 Boolean 則不是。 | 
| 物件 | 序列化為 JSON 的物件。JSON 字串是首尾以大括號括住，並以逗號分隔的鍵值組清單。String 在括號中。Decimal、Int、Boolean 和 Null 則不是。 | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## ceil(Decimal)
<a name="iot-func-ceil"></a>

將指定的 `Decimal` 無條件進位至最近的 `Int`。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`ceil(1.2)` = 2

`ceil(-1.2)` = -1


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Int，引數值。 | 
| Decimal | Int，無條件進位至最接近的 Decimal 的 Int 值。 | 
| String | Int。此字串會轉換成 Decimal 並四捨五入至最接近 Int。如果字串無法轉換為 Decimal，則結果為 Undefined。 | 
| 其他值 | Undefined. | 

## chr(String)
<a name="iot-func-chr"></a>

傳回指定的 `Int` 引數對應到的 ASCII 字元。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`chr(65)` = "A"。

`chr(49)` = "1"。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | 對應到指定的 ASCII 值的字元。如果引數並非有效的 ASCII 值，結果會為 Undefined。 | 
| Decimal | 對應到指定的 ASCII 值的字元。Decimal 的引數值會無條件捨去至最接近 Int 的值。如果引數並非有效的 ASCII 值，結果會為 Undefined。 | 
| Boolean | Undefined. | 
| String | 如果 String 可以轉換為 Decimal，要無條件捨去到最接近的 Int。如果引數並非有效的 ASCII 值，結果會為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 其他值 | Undefined. | 

## clientid()
<a name="iot-sql-function-clientid"></a>

傳回傳送訊息的 MQTT 用戶端的 ID，如果訊息不是透過 MQTT 傳送，則為 `n/a`。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`clientid() ` = "123456789012"

## concat()
<a name="iot-func-concat"></a>

連接陣列或字串。此函數會接受任意數量的引數，並傳回 `String` 或 `Array`。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`concat() ` = `Undefined`.

`concat(1) ` = "1"。

`concat([1, 2, 3], 4)` = [1, 2, 3, 4]。

`concat([1, 2, 3], "hello")` = [1, 2, 3, "hello"]

`concat("con", "cat")` = "concat"

`concat(1, "hello")` = "1hello"

`concat("he","is","man")` = "heisman"

`concat([1, 2, 3], "hello", [4, 5, 6])` = [1, 2, 3, "hello", 4, 5, 6]


****  

| 引數數量 | 結果 | 
| --- | --- | 
| 0 | Undefined. | 
| 1 | 傳回的引數未經修改。 | 
| 2\$1 |  如果任一引數為 `Array`，則結果會是包含所有引數的單一陣列。若沒有列出引數，且至少有一個引數是 `String`，則結果為所有引數 `String` 表示法的串聯。使用之前列出的標準轉換將引數轉換為字串。  | 

## cos(Decimal)
<a name="iot-func-cos"></a>

以弧度傳回數字的餘弦值。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`cos(0)` = 1。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，引數的餘弦值。傳回的虛數結果為 Undefined。 | 
| Decimal | Decimal (使用雙精度)，引數的餘弦值。傳回的虛數結果為 Undefined。 | 
| Boolean | Undefined. | 
| String | Decimal (使用雙精度)，引數的餘弦值。如果字串無法轉換為 Decimal，則結果為 Undefined。傳回的虛數結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## cosh(Decimal)
<a name="iot-func-cosh"></a>

以弧度傳回數字的雙曲餘弦值。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`cosh(2.3)` = 5.037220649268761。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，引數的雙曲餘弦值。傳回的虛數結果為 Undefined。 | 
| Decimal | Decimal (使用雙精度)，引數的雙曲餘弦值。傳回的虛數結果為 Undefined。 | 
| Boolean | Undefined. | 
| String | Decimal (使用雙精度)，引數的雙曲餘弦值。如果字串無法轉換為 Decimal，則結果為 Undefined。傳回的虛數結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## decode(value, decodingScheme)
<a name="iot-sql-decode-base64"></a>

使用 `decode` 函數來解碼已編碼值。如果解碼字串為 JSON 文件，則會傳回可定址物件。否則，解碼字串會當成字串傳回。如果字串無法解碼，函數會傳回 NULL。此功能支援解碼 base64 編碼字串及協定緩衝區 (protobuf) 訊息格式。

受 SQL 版本 2016-03-23 和更新版本支援。

value  
字串值或任何有效的表達式 (如 [AWS IoT SQL 參考](iot-sql-reference.md) 所定義)，其會傳回字串。

decodingScheme  
代表用來解碼值之結構描述的文字字串。目前僅支援 `'base64'` 和 `'proto'`。

### 對 base64 編碼字串進行解碼
<a name="iot-sql-decode-example"></a>

在此範例中，訊息承載包含編碼值。

```
{
    encoded_temp: "eyAidGVtcGVyYXR1cmUiOiAzMyB9Cg=="
}
```

SQL 陳述式中的 `decode` 函數會解碼訊息承載中的值。

```
SELECT decode(encoded_temp,"base64").temperature AS temp from 'topic/subtopic'
```

解碼 `encoded_temp` 值會產生下列有效的 JSON 文件，允許 SELECT 陳述式讀取溫度值。

```
{ "temperature": 33 }
```

這裡顯示此範例中 SELECT 陳述式的結果。

```
{ "temp": 33 }
```

如果解碼值不是有效的 JSON 文件，解碼值將以字串形式傳回。

### 對 protobuf 訊息承載進行解碼
<a name="iot-sql-decode-protobuf"></a>

您可以使用解碼 SQL 函數來設定可對 protobuf 訊息承載進行解碼的規則。如需詳細資訊，請參閱[對 protobuf 訊息承載進行解碼](binary-payloads.md#binary-payloads-protobuf)。

**重要**  
如果您在設定 AWS IoT 委託人的許可`source‐account`時省略 `source‐arn`或 ，任何 AWS 帳戶 都可以透過其他 AWS IoT 規則叫用您的解碼函數。若要保護您的函數，請參閱《*Amazon Simple Storage Service 使用者指南*》中的[儲存貯體政策](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-policies.html)。

功能簽章外觀如下：

```
decode(<ENCODED DATA>, 'proto', '<S3 BUCKET NAME>', '<S3 OBJECT KEY>', '<PROTO NAME>', '<MESSAGE TYPE>')            
```

`ENCODED DATA`  
指定要解碼的 protobuf 編碼資料。如果傳送到規則的整個訊息是 protobuf 編碼資料，則可以使用 `*` 參考原始二進位傳入承載。否則，此欄位必須是 base-64 編碼的 JSON 字串，而且可以直接傳入字串的參考。  
1) 要解碼原始二進位 protobuf 傳入承載：  

```
decode(*, 'proto', ...)
```
2）要解碼由 base64 編碼字串 'a.b'表示的 protobuf 編碼訊息：  

```
decode(a.b, 'proto', ...)
```

`proto`  
指定要以 protobuf 訊息格式解碼的資料。如果您指定 `base64` 而不是 `proto`，此函數會將 base64 編碼字串解碼為 JSON。

`S3 BUCKET NAME`  
您用來上傳 `FileDescriptorSet` 檔案的 Amazon S3 儲存貯體名稱。

`S3 OBJECT KEY`  
用來在 Amazon S3 儲存貯體中指定 `FileDescriptorSet` 檔案的物件索引鍵。

`PROTO NAME`  
從中產生 `FileDescriptorSet` 檔案的 `.proto` 檔案名稱 (不含副檔名)。

`MESSAGE TYPE`  
待解碼資料在 `FileDescriptorSet` 檔案中所應符合的 Protobuf 訊息結構名稱。

使用解碼 SQL 函數的 SQL 運算式可能顯示如下：

```
SELECT VALUE decode(*, 'proto', 's3-bucket', 'messageformat.desc', 'myproto', 'messagetype') FROM 'some/topic'
```
+ `*`

  表示二進位傳入承載，符合名為 `mymessagetype` 的 Protobuf 訊息類型。
+ `messageformat.desc`

  存放在名為 `s3-bucket` 的 Amazon S3 儲存貯體中的 `FileDescriptorSet` 檔案。
+ `myproto`

  此原始 `.proto` 檔案的用途是產生名為 `myproto.proto` 的 `FileDescriptorSet` 檔案。
+ `messagetype`

  如 `myproto.proto` 中所定義名為 `messagetype` 的訊息類型(以及任何匯入的相依性)。

## encode(value, encodingScheme)
<a name="iot-sql-encode-payload"></a>

根據編碼機制，使用 `encode` 函數將承載 (可能並非 JSON 資料) 編碼為字串表現形式。受 SQL 版本 2016-03-23 和更新版本支援。

value  
任何有效的表達式，如 [AWS IoT SQL 參考](iot-sql-reference.md) 的定義。無論承載是否為 JSON 格式，您都可以指定 \$1 以編碼整個承載。若您提供了運算式，則在編碼之前，評估結果將轉換為字串。

encodingScheme  
代表您想要使用的編碼機制的文字字串。目前僅支援 `'base64'`。

## endswith(String, String)
<a name="iot-func-endswith"></a>

傳回 `Boolean`，指出第一個 `String` 引數是否以第二個 `String` 引數結尾。如果引數為 `Null` 或 `Undefined`，則結果為 `Undefined`。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`endswith("cat","at")` = true。


****  

| 引數類型 1 | 引數類型 2 | 結果 | 
| --- | --- | --- | 
| String | String | 如果第一個引數以第二個引數結尾，則為 true。否則為 false。 | 
| 其他值 | 其他值 | 所有引數都將使用標準轉換規則轉換為字串。如果第一個引數以第二個引數結尾，則為 true。否則為 false。如果引數為 Null 或 Undefined，則結果為 Undefined。 | 

## exp(Decimal)
<a name="iot-func-exp"></a>

傳回 e 次方的 `Decimal` 引數。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`exp(1)` = e。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，e ^ 引數。 | 
| Decimal | Decimal (使用雙精度)，e ^ 引數。 | 
| String | Decimal (使用雙精度)，e ^ 引數。如果 String 無法轉換為 Decimal，則結果為 Undefined。 | 
| 其他值 | Undefined. | 

## floor(Decimal)
<a name="iot-func-floor"></a>

將指定的 `Decimal` 無條件進位至最接近的 `Int`。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`floor(1.2)` = 1

`floor(-1.2)` = -2


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Int，引數值。 | 
| Decimal | Int，Decimal 值會無條件捨去至最接近的 Int。 | 
| String | Int。此字串會轉換成 Decimal，並無條件捨去至最接近的 Int。如果字串無法轉換為 Decimal，則結果為 Undefined。 | 
| 其他值 | Undefined. | 

## get
<a name="iot-sql-function-get"></a>

從集合類型 (陣列、字串、物件) 擷取值。第一個引數不會套用任何轉換。轉換會按表格中的記錄套用至第二個引數。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`get(["a", "b", "c"], 1) ` = "b"

`get({"a":"b"}, "a")` = "b"

`get("abc", 0)` = "a"


****  

| 引數類型 1 | 引數類型 2 | 結果 | 
| --- | --- | --- | 
| 陣列 | 任何類型 (轉換為 Int) | 第二個引數 (轉換為 Array) 所提供的 Int 從零開始的索引的項目。如果轉換不成功，則結果為 Undefined。如果索引在 Array的邊界之外 (負值或 >= array.length)，則結果為 Undefined。 | 
| String | 任何類型 (轉換為 Int) | 第二個引數 (轉換為 Int) 所提供的字串從零開始的索引的字元。如果轉換不成功，則結果為 Undefined。如果索引在字串的邊界之外 (負值或 >= string.length)，則結果為 Undefined。 | 
| 物件 | String (未套用轉換) | 對應至第二個引數所提供的字串鍵的第一個引數物件所儲存的值。 | 
| 其他值 | 任何值 | Undefined. | 

## get\$1dynamodb(tableName, partitionKeyName, partitionKeyValue, sortKeyName, sortKeyValue, roleArn)
<a name="iot-sql-function-get-dynamodb"></a>

從 DynamoDB 資料表擷取資料。`get_dynamodb()` 允許您在評估規則時查詢 DynamoDB 資料表。您可以使用從 DynamoDB 中擷取的資料來篩選或增強訊息承載。受 SQL 版本 2016-03-23 和更新版本支援。

`get_dynamodb()` 接受下列參數：

tableName  
所要查詢 DynamoDB 資料表的名稱。

partitionKeyName  
分割區索引鍵的名稱。如需詳細資訊，請參閱 [DynamoDB 索引鍵](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)。

partitionKeyValue  
用來識別記錄的分割區索引鍵值。如需詳細資訊，請參閱 [DynamoDB 索引鍵](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)。

sortKeyName  
(選用) 排序索引鍵的名稱。只有在查詢的 DynamoDB 資料表使用複合索引鍵時，才需要此參數。如需詳細資訊，請參閱 [DynamoDB 索引鍵](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)。

sortKeyValue  
(選用) 排序索引鍵的值。只有在查詢的 DynamoDB 資料表使用複合索引鍵時，才需要此參數。如需詳細資訊，請參閱 [DynamoDB 索引鍵](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)。

roleArn  
授予 DynamoDB 資料表存取權限的 IAM 角色 ARN。規則引擎會假設此角色代表您存取 DynamoDB 資料表。請避免使用過多許可的角色。僅授與角色規則所需的許可。以下是授與一個 DynamoDB 資料表存取權的範例政策。    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "dynamodb:GetItem",
            "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/table-name"
        }
    ]
}
```

舉例說明如何使用 `get_dynamodb()`，假設您有一個 DynamoDB 資料表，其中包含所有連接至 AWS IoT之裝置的裝置 ID 和位置資訊。下列 SELECT 陳述式使用 `get_dynamodb()` 函數來擷取指定裝置 ID 的位置：

`SELECT *, get_dynamodb("InServiceDevices", "deviceId", id, "arn:aws:iam::12345678910:role/getdynamo").location AS location FROM 'some/topic' `

**注意**  
每個 SQL 陳述式最多可以呼叫一次 `get_dynamodb()`。在單一 SQL 陳述式中多次呼叫 `get_dynamodb()` 會導致規則終止，而不會呼叫任何動作。

## get\$1mqtt\$1property(名稱)
<a name="iot-sql-function-get-mqtt-property"></a>

參考下列任一 MQTT5 標頭：`contentType`、`payLoadFormatIndicator`、`responseTopic`、和 `correlationData`。此函數會接受下列任何常值字串做為引數：`content_type`、`format_indicator`、`response_topic` 和 `correlation_data`。如需詳細資訊，請參閱下列**函數引數**表。

ContentType  
字串：描述發佈訊息內容的 UTF-8 編碼字串。

payLoadFormatIndicator  
字串：列舉字串值，用於表示承載是否已格式化為 UTF-8。有效值為 `UNSPECIFIED_BYTES` 和 `UTF8_DATA`。

responseTopic  
字串：UTF-8 編碼字串，用來當作回應訊息的主題名稱。回應主題是用來描述要在請求-回應流程中作為接收者發佈目標的主題。主題不得包含萬用字元。

correlationData  
字串：請求訊息的傳送者使用 base64 編碼的二進位資料，用以在收到回應訊息時識別其所對應的請求。

下表列出可接受的函數引數及其相關聯的 `get_mqtt_property` 函數傳回類型：


**函數引數**  

| SQL | 傳回資料類型 (如果存在) | 傳回資料類型 (如果不存在) | 
| --- | --- | --- | 
| get\$1mqtt\$1property("format\$1indicator") | 字串 (UNSPECIFIED\$1BYTES 或 UTF8\$1DATA) | 字串 (NSPECIFIED\$1BYTES) | 
| get\$1mqtt\$1property("content\$1type") | String | 未定義 | 
| get\$1mqtt\$1property("response\$1topic") | String | 未定義 | 
| get\$1mqtt\$1property("correlation\$1data") | base64 編碼字串 | 未定義 | 
| get\$1mqtt\$1property("some\$1invalid\$1name") | 未定義 | 未定義 | 

下列範例規則 SQL 會參考下列任一 MQTT5 標頭：`contentType`、`payLoadFormatIndicator`、`responseTopic`、和`correlationData`。

```
SELECT *, get_mqtt_property('content_type') as contentType,
          get_mqtt_property('format_indicator') as payloadFormatIndicator,
          get_mqtt_property('response_topic') as responseTopic,
          get_mqtt_property('correlation_data') as correlationData
FROM 'some/topic'
```

## get\$1or\$1default(expression， defaultValue)
<a name="iot-sql-function-get-or-default"></a>

如果指定，則傳回第二個參數中的預設值，否則當第一個參數中的運算式傳回 null、未定義或失敗時，傳回未定義的預設值。受 SQL 版本 2016-03-23 和更新版本支援。

**重要**  
`get_or_default` 不如預期直接支援非 JSON 承載。如果您使用的是非 JSON 承載，請使用 `encode`或 `decode`函數。

`get_or_default()` 接受下列參數：

表達式  
任何包含 [資料類型](iot-sql-data-types.md)、[函數](#iot-sql-functions)、[文字](iot-sql-literals.md)、[變數](iot-sql-set.md#iot-sql-set-usage)[巢狀物件查詢](iot-sql-nested-queries.md)、 或 的有效表達式[JSON Extensions](iot-sql-json.md)。

defaultValue  
（選用） 包含 [資料類型](iot-sql-data-types.md)、[函數](#iot-sql-functions)、[文字](iot-sql-literals.md)、[變數](iot-sql-set.md#iot-sql-set-usage)[巢狀物件查詢](iot-sql-nested-queries.md)、 或 的任何有效表達式[JSON Extensions](iot-sql-json.md)。這是當第一個引數傳回 null、未定義或失敗時要傳回的值。  
defaultValue 參數不允許從客戶擁有的資源擷取資料的函數，例如 get\$1secret、get\$1dynamodb、aws\$1lambda、get\$1thing\$1shadow、decode-protobuf 和 machinelearning\$1predict。

下表顯示每個引數及其相關聯輸出可接受的函數引數：


| 第一個引數 | 第二個引數 | Output | 
| --- | --- | --- | 
| 成功的評估 | 任何值或未指定 | 第一個引數值。 | 
| 未定義、Null 或失敗 | 任何值，包括未定義或 Null | 第二個引數值。 | 
| 未定義、Null 或失敗 | 未指定 | Undefined | 

**範例**：

範例 1：

如果 DynamoDB 資料表或查詢失敗，下列範例會提供 defaultValue 值：

```
SELECT 
    device_id,
    get_or_default(
        get_dynamodb("DeviceConfig", "deviceId", nonExistentId, "arn:aws:iam::123456789012:role/ROLE_NAME"),
        {"mode": "standard", "timeout": 30, "enabled": true }
    ) as config
FROM 'device/telemetry'
```

範例 2：

如果狀態為未定義，以下範例會提供安全的預設值 "UNKNOWN"：

```
SELECT 
  get_or_default( CASE status
    WHEN 'active' THEN 'GOOD'
    WHEN 'inactive' THEN 'BAD'/
    ELSE 'UNKNOWN'
  END, 'UNKNOWN') as status_category
FROM 'topic/subtopic'
```

範例 3：

下列範例示範如何搭配單一參數使用 get\$1or\$1default。這在您可能沒有明確的預設值，但不希望規則執行失敗的情況下非常有用。

```
SELECT 
  get_dynamodb("DeviceConfig", "deviceId", nonExistentId, "arn:aws:iam::123456789012:role/ROLE_NAME") as config
FROM 'device/telemetry'
```

如果 DynamoDB 查詢失敗，規則執行將會失敗，而且不會執行任何動作。如果改用下列 SQL：

```
SELECT 
  get_or_default(get_dynamodb("DeviceConfig", "deviceId", nonExistentId, "arn:aws:iam::123456789012:role/ROLE_NAME")) as config
FROM 'device/telemetry'
```

get\$1or\$1default 陳述式將評估為 `Undefined`，因此在此範例中，整體 SELECT 陳述式將評估為 `{}`，並嘗試任何規則動作。

**重要**  
建議您遵循這些最佳實務，以維護使用此函數時的安全性：  
避免在規則定義中使用硬式編碼秘密，包括預設值
使用 AWS Secrets Manager 管理敏感資訊

## get\$1registry\$1data(registryAPI， thingName， roleArn)
<a name="iot-sql-function-get-registry-data"></a>

擷取 AWS IoT 規則中的 AWS IoT 物件登錄檔資料。您可以讀取登錄檔資料 （例如屬性、物件類型和裝置所屬的物件群組），並使用此資訊來篩選、豐富或動態路由訊息。受 SQL 版本 2016-03-23 和更新版本支援。

`get_registry_data()` 接受下列參數：

registryAPI  
正在呼叫的登錄 API。有效值為 `DescribeThing` 和 `ListThingGroupsForThing`。這些值必須是常數字串。

thingName  
字串：您要擷取其登錄檔資料之物件的名稱。

roleArn  
字串：根據所呼叫 API 具有`iot:DescribeThing`許可和/或`iot:ListThingGroupsForThing`許可的角色 ARN。

`get_registry_data` 函數的回應格式與呼叫的登錄 API 相同。如需詳細資訊，請參閱 [DescribeThing](https://docs.aws.amazon.com//iot/latest/apireference/API_DescribeThing.html) 和 [ListThingGroupsForThing](https://docs.aws.amazon.com//iot/latest/apireference/API_ListThingGroupsForThing.html) APIs。

範例：

您可以擷取物件類型資訊，以允許篩選物件類型為 之物件 （物件名稱符合 MQTT 用戶端 ID) 的 AWS IoT Core 生命週期事件訊息`testenv`。

```
SELECT * 
FROM '$aws/events/lifecycle/+' 
WHERE 
    get_registry_data("DescribeThing",clientId,[roleArn]).thingTypeName='testenv'
```

範例：

您可以為閘道裝置 傳送`sensor1`的所有訊息擷取物件名稱的裝置物件屬性`gateway1`。

```
SELECT *, get_registry_data("DescribeThing","sensor1",[roleArn]).attributes.temperature_threhold AS device1_tempthreshold 
FROM home1/gateway1/sensor1/#
```

**注意**  
每個 SQL 陳述式和動作和錯誤動作的替代範本`get_registry_data()`最多可以呼叫一次。

## get\$1secret(secretId, secretType, key, roleArn)
<a name="iot-sql-function-get-secret"></a>

擷取所加密 `SecretString` 或 `SecretBinary` 欄位的值，此欄位是 [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/) 中目前秘密版本的欄位。如需建立和維護秘密的詳細資訊，請參閱 [CreateSecret](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_CreateSecret.html)、[UpdateSecret](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_UpdateSecret.html) 和 [PutSecretValue](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_PutSecretValue.html)。

`get_secret()` 接受下列參數：

secretId  
字串：要擷取之秘密的 Amazon 資源名稱 (ARN) 或易記名稱。

secretType  
字串：秘密類型。有效值：`SecretString` \$1 `SecretBinary`。    
SecretString  
+ 對於您使用 APIs AWS CLI、 或 AWS Secrets Manager 主控台建立為 JSON 物件的秘密：
  + 如果您指定 `key` 參數的值，此函數會傳回所指定金鑰的值。
  + 如果未指定 `key` 參數的值，此函數會傳回整個 JSON 物件。
+ 對於您使用 API 或 AWS CLI建立為非 JSON 物件的秘密：
  + 如果您指定 `key` 參數的值，此函數會失敗並顯示例外狀況。
  + 如果未指定 `key` 參數的值，此函數會傳回秘密的內容。  
SecretBinary  
+ 如果您指定 `key` 參數的值，此函數會失敗並顯示例外狀況。
+ 如果未指定 `key` 參數的值，此函數會以 Base64 編碼的 UTF-8 字串形式傳回秘密值。

key  
(選用) 字串：JSON 物件內的金鑰名稱，此物件存放在秘密的 `SecretString` 欄位中。當您只想要擷取存放在秘密中的秘密值，而不是整個 JSON 物件時，請使用此值。  
如果您指定此參數的值，而且秘密並未在其 `SecretString` 欄位內包含 JSON 物件，此函數會失敗並顯示例外狀況。

roleArn  
字串：擁有 `secretsmanager:GetSecretValue` 和 `secretsmanager:DescribeSecret` 許可的角色 ARN。

**注意**  
此函數一律傳回目前版本的秘密 (標籤為 `AWSCURRENT` 的版本)。 AWS IoT 規則引擎會快取每個秘密最多 15 分鐘。因此，規則引擎最多可能需要 15 分鐘來更新秘密。這表示如果您在使用 更新後最多 15 分鐘內擷取秘密 AWS Secrets Manager，此函數可能會傳回先前的版本。  
此函數不會計量，但會 AWS Secrets Manager 收取費用。由於秘密快取機制，規則引擎偶爾會呼叫 AWS Secrets Manager。因為規則引擎是完全分散式服務，您可能會在 15 分鐘快取時間範圍期間，看到多個來自規則引擎的 Secrets Manager API 呼叫。

範例：

您可以在 HTTPS 規則動作的身分驗證標題中使用 `get_secret` 函式，如下列 API 金鑰身分驗證範例所示。

```
"API_KEY": "${get_secret('API_KEY', 'SecretString', 'API_KEY_VALUE', 'arn:aws:iam::12345678910:role/getsecret')}"
```

如需 HTTPS 規則動作的詳細資訊，請參閱 [HTTP](https-rule-action.md)。

## get\$1thing\$1shadow(thingName， shadowName， roleArn)
<a name="iot-sql-function-get-thing-shadow"></a>

傳回指定物件的影子。受 SQL 版本 2016-03-23 和更新版本支援。

thingName  
字串：想要擷取影子的物件名稱。

shadowName  
(選用) 字串：影子的名稱。只有在參考已命名的影子時，才需要此參數。

roleArn  
字串：擁有 `iot:GetThingShadow` 許可的角色 ARN。

範例：

與已命名的影子搭配使用時，請提供 `shadowName` 參數。

```
SELECT * from 'topic/subtopic'
WHERE
    get_thing_shadow("MyThing","MyThingShadow","arn:aws:iam::123456789012:role/AllowsThingShadowAccess")
    .state.reported.alarm = 'ON'
```

與未命名影子搭配使用時，請省略 `shadowName` 參數。

```
SELECT * from 'topic/subtopic'
WHERE
    get_thing_shadow("MyThing","arn:aws:iam::123456789012:role/AllowsThingShadowAccess")
    .state.reported.alarm = 'ON'
```

## get\$1user\$1properties(userPropertyKey)
<a name="iot-sql-function-get-user-properties"></a>

參考使用者屬性，這是 MQTT5 支援的一種屬性標題類型。

userProperty  
字串：使用者屬性是索引鍵/值對。此函數將索引鍵當作參數，並傳回所有符合關聯索引鍵的值陣列。

**函數引數**

對於下列位於訊息標頭中的使用者屬性：


| 金鑰 | 值 | 
| --- | --- | 
| 部分索引鍵 | 部分值 | 
| 不同的索引鍵 | 不同的值 | 
| 部分索引鍵 | 具有重複索引鍵的值 | 

下表顯示預期的 SQL 行為：


| SQL | 傳回資料類型。 | 傳回資料類型。 | 
| --- | --- | --- | 
| get\$1user\$1properties(「部分索引鍵」) | 字串陣列 | ['some value', 'value with duplicate key'] | 
| get\$1user\$1properties(「其他索引鍵」) | 字串陣列 | ['a different value'] | 
| get\$1user\$1properties( ) | 索引鍵/值對物件的陣列 | [\$1'"some key": "some value"'\$1, \$1"other key": "a different value"\$1, \$1"some key": "value with duplicate key"\$1] | 
| get\$1user\$1properties(「不存在的索引鍵」) | 未定義 |  | 

下列範例規則 SQL 會將使用者屬性 (MQTT5 屬性標頭類型) 參考到承載中：

```
SELECT *, get_user_properties('user defined property key') as userProperty
FROM 'some/topic'
```

## 雜湊函數
<a name="iot-sql-function-hash"></a>

 AWS IoT 提供下列雜湊函數：
+ md2
+ md5
+ sha1
+ sha224
+ sha256
+ sha384
+ sha512

所有雜湊函數都預期有一個字串引數。結果為該字串的雜湊值。標準字串轉換會套用至非字串的引數。SQL 版本 2015-10-08 和更新版本可支援所有雜湊函數。

範例：

`md2("hello")` = "a9046c73e00331af68917d3804f70655"

`md5("hello")` = "5d41402abc4b2a76b9719d911017c592"

## indexof(String, String)
<a name="iot-sql-function-indexof"></a>

傳回第二個引數的第一個索引 (從 0 開始)，作為第一個引數的子字串。預期兩個引數均為字串。非字串的引數需遵守標準字串轉換規則。此函數不能套用在陣列上，僅可套用到字串上。受 SQL 版本 2016-03-23 和更新版本支援。

範例：

`indexof("abcd", "bc") ` = 1

## isNull()
<a name="iot-sql-function-isNull"></a>

如果引數是 `Null` 值，則傳回 true 受 SQL 版本 2016-03-23 和更新版本支援。

範例：

`isNull(5) ` = false。

`isNull(Null) ` = true。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | false | 
| Decimal | false | 
| Boolean | false | 
| String | false | 
| Array | false | 
| Object | false | 
| Null | true | 
| Undefined | false | 

## isUndefined()
<a name="iot-sql-function-isUndefined"></a>

如果引數是 `Undefined`，則傳回 true。受 SQL 版本 2016-03-23 和更新版本支援。

範例：

`isUndefined(5) ` = false。

`isUndefined(floor([1,2,3]))) ` = true。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | false | 
| Decimal | false | 
| Boolean | false | 
| String | false | 
| Array | false | 
| Object | false | 
| Null | false | 
| Undefined | true | 

## length(String)
<a name="iot-sql-function-length"></a>

傳回所提供的字串內的字元數。標準轉換規則會套用至非 `String` 的引數。受 SQL 版本 2016-03-23 和更新版本支援。

範例：

`length("hi")` = 2

`length(false)` = 5

## ln(Decimal)
<a name="iot-func-nln"></a>

傳回引數的自然對數。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`ln(e)` = 1。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，引數的自然對數。 | 
| Decimal | Decimal (使用雙精度)，引數的自然對數。 | 
| Boolean | Undefined. | 
| String | Decimal (使用雙精度)，引數的自然對數。如果字串無法轉換為 Decimal，則結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## log(Decimal)
<a name="iot-func-log"></a>

傳回引數以 10 為底的對數。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`log(100)` = 2.0。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，引數以 10 為底的對數。 | 
| Decimal | Decimal (使用雙精度)，引數以 10 為底的對數。 | 
| Boolean | Undefined. | 
| String | Decimal (使用雙精度)，引數以 10 為底的對數。如果 String 無法轉換為 Decimal，則結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## lower(String)
<a name="iot-func-lower"></a>

傳回小寫版本的特定 `String`。使用標準轉換規則將非字串引數轉換為字串。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`lower("HELLO")` =「hello」。

`lower(["HELLO"])` = "[\$1"hello\$1"]".

## lpad(String, Int)
<a name="iot-func-lpad"></a>

傳回 `String` 引數，左側填入第二個引數所指定的空格數。`Int` 引數必須介於 0 到 1000 之間。如果提供的值超出此有效範圍，則引數將設為最接近的有效值 (0 或 1000)。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`lpad("hello", 2)` = "`  hello`".

`lpad(1, 3)` = "`   1`"


****  

| 引數類型 1 | 引數類型 2 | 結果 | 
| --- | --- | --- | 
| String | Int | String，所給的 String 左側填入等同所給的 Int 的數量的空格。 | 
| String | Decimal | Decimal 引數將無條件捨去至最接近的 Int，而 String 會在左側填充指定的空格數。 | 
| String | String | 第二個引數會轉換為 Decimal 並無條件捨去至最接近的 Int，而 String 會在左側填入指定的空格數。如果第二個引數無法轉換為 Int，則結果為 Undefined。 | 
| 其他值 | Int/Decimal/String | 第一個值會使用標準轉換轉為 String，然後 LPAD 函數會套用至該 String。如果其無法轉換，則結果為 Undefined。 | 
| 任何值 | 其他值 | Undefined. | 

## ltrim(String)
<a name="iot-func-ltrim"></a>

移除所給的 `String` 前方所有空格 (tab 與空格)。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`Ltrim(" h i ")` = "hi "。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | 移除 Int 前方所有空格的 String 顯示方式。 | 
| Decimal | 移除 Decimal 前方所有空格的 String 顯示方式。 | 
| Boolean | 移除布林值 (「true」或「false」) 前方所有空格的 String 顯示方式。 | 
| String | 移除前方所有空格的引數。 | 
| 陣列 | String (使用標準轉換規則) 的 Array 顯示方式，且移除所有前置空格。 | 
| 物件 | Object (使用標準轉換規則) 的 String 顯示方式，且移除所有前置空格。 | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## machinelearning\$1predict(modelId, roleArn, record)
<a name="iot-sql-function-machine-learning"></a>

使用 `machinelearning_predict`函數，根據 Amazon SageMaker AI 模型使用來自 MQTT 訊息的資料進行預測。受 SQL 版本 2015-10-08 和更新版本支援。`machinelearning_predict` 函數的引數如下：

modelId  
要對其執行預測的模型 ID。必須啟用該模型的即時端點。

roleArn  
IAM 角色具有擁有 `machinelearning:Predict` 和 `machinelearning:GetMLModel` 許可的政策，且允許存取要對其執行預測的模型。

record  
要傳遞至 SageMaker AI 預測 API 的資料。此應顯示為單層 JSON 物件。若該記錄為多層級 JSON 物件，則記錄會透過值的序列化來扁平化。例如，以下 JSON：  

```
{ "key1": {"innerKey1": "value1"}, "key2": 0}
```
 會變成：  

```
{ "key1": "{\"innerKey1\": \"value1\"}", "key2": 0}
```

該函數會傳回具有以下欄位的 JSON 物件：

predictedLabel  
根據模型的輸入分類。

詳細資訊  
包含下列屬性：    
PredictiveModelType  
模型類型。有效值為 REGRESSION、BINARY、MULTICLASS。  
演算法  
SageMaker AI 用來進行預測的演算法。該值必須為 SGD。

predictedScores  
包含對應至每個標籤的原始分類分數。

predictedValue  
SageMaker AI 預測的值。

## mod(Decimal, Decimal)
<a name="iot-func-mod"></a>

傳回第一個引數除以第二的引數的餘數。等同於 [remainder(Decimal, Decimal)](#iot-func-remainder)。也可以使用「%」當做同樣的模除功能的 infix 運算子。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`mod(8, 3)` = 2。


****  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int | Int | Int，第一個引數模除第二個引數。 | 
| Int/Decimal | Int/Decimal | Decimal，第一個引數模除第二個運算元。 | 
| String/Int/Decimal | String/Int/Decimal | 如果所有的字串都轉換為小數，該結果是第一個引數以第二個引數為模。否則為 Undefined。 | 
| 其他值 | 其他值 | Undefined. | 

## nanvl(AnyValue, AnyValue)
<a name="iot-func-nanvl"></a>

若第一個引數為有效的 `Decimal`，即傳回。否則便傳回第二個引數。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`Nanvl(8, 3)` = 8。


****  

| 引數類型 1 | 引數類型 2 | Output | 
| --- | --- | --- | 
| 未定義 | 任何值 | 第二個參數。 | 
| Null | 任何值 | 第二個參數。 | 
| Decimal (NaN) | 任何值 | 第二個參數。 | 
| Decimal (非 NaN) | 任何值 | 第一個參數。 | 
| 其他值 | 任何值 | 第一個參數。 | 

## newuuid()
<a name="iot-sql-function-newuuid"></a>

傳回隨機的 16 位元組 UUID。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`newuuid()` = `123a4567-b89c-12d3-e456-789012345000`

## numbytes(String)
<a name="iot-sql-function-numbytes"></a>

傳回所給字串 UTF-8 編碼中的位元組數。標準轉換規則會套用至非 `String` 的引數。受 SQL 版本 2016-03-23 和更新版本支援。

範例：

`numbytes("hi")` = 2

`numbytes("€") ` = 3

## parse\$1time(String, Long[, String])
<a name="iot-sql-function-parse-time"></a>

使用 `parse_time` 函數來設定時間戳記格式，變成人類易懂的日期/時間格式。受 SQL 版本 2016-03-23 和更新版本支援。若要將時間戳記字串轉換為毫秒，請參閱 [time\$1to\$1epoch(String, String)](#iot-sql-function-time-to-epoch)。

`parse_time` 函數預期下列引數：

pattern  
(字串) 遵循 [Joda-Time 格式](http://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html)的日期/時間模式。

timestamp  
(Long) 自 Unix epoch 起以毫秒單位設定格式的時間。請參閱函數 [timestamp()](#iot-function-timestamp)。

timezone  
(字串) 設定好格式的日期/時間的時區。預設值為「UTC」。該函數支援 [Joda-Time 時區](http://joda-time.sourceforge.net/timezones.html)。此為選用引數。

範例：

在此訊息發佈至主題「A/B」時，承載 `{"ts": "1970.01.01 AD at 21:46:40 CST"}` 會傳送至 S3 儲存貯體：

```
{
    "ruleArn": "arn:aws:iot:us-east-2:ACCOUNT_ID:rule/RULE_NAME",
    "topicRulePayload": {
        "sql": "SELECT parse_time(\"yyyy.MM.dd G 'at' HH:mm:ss z\", 100000000, 'America/Belize' ) as ts FROM 'A/B'",

        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "s3": {
                    "roleArn": "arn:aws:iam::ACCOUNT_ID:rule:role/ROLE_NAME",
                    "bucketName": "BUCKET_NAME",
                    "key": "KEY_NAME"
                }
            }
        ],
        "ruleName": "RULE_NAME"
    }
}
```

在此訊息發佈至主題「A/B」時，與 `{"ts": "2017.06.09 AD at 17:19:46 UTC"}` 相似，但包含目前日期/時間的承載會傳送至 S3 儲存貯體：

```
{
    "ruleArn": "arn:aws:iot:us-east-2:ACCOUNT_ID:rule/RULE_NAME",
    "topicRulePayload": {
        "sql": "SELECT parse_time(\"yyyy.MM.dd G 'at' HH:mm:ss z\", timestamp() ) as ts FROM 'A/B'",
        "awsIotSqlVersion": "2016-03-23",
        "ruleDisabled": false,
        "actions": [
            {
                "s3": {
                    "roleArn": "arn:aws:iam::ACCOUNT_ID:rule:role/ROLE_NAME",
                    "bucketName": "BUCKET_NAME",
                    "key": "KEY_NAME"
                }
            }
        ],
        "ruleName": "RULE_NAME"
    }
}
```

`parse_time()` 也可以用作替代範本。例如，當此訊息發佈至主題「A/B」時，該承載會傳送至金鑰 =「2017」的 S3 儲存貯體：

```
{
    "ruleArn": "arn:aws:iot:us-east-2:ACCOUNT_ID:rule/RULE_NAME",
    "topicRulePayload": {
        "sql": "SELECT * FROM 'A/B'",
        "awsIotSqlVersion": "2016-03-23",
        "ruleDisabled": false,
        "actions": [{
            "s3": {
                "roleArn": "arn:aws:iam::ACCOUNT_ID:rule:role/ROLE_NAME",
                "bucketName": "BUCKET_NAME",
                "key": "${parse_time('yyyy', timestamp(), 'UTC')}"
            }
        }],
        "ruleName": "RULE_NAME"
    }
}
```

## power(Decimal, Decimal)
<a name="iot-func-power"></a>

傳回第一個引數次方的第二個引數值。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`power(2, 5)` = 32.0。


****  

| 引數類型 1 | 引數類型 2 | Output | 
| --- | --- | --- | 
| Int/Decimal | Int/Decimal | Decimal (使用雙精度)，第一個引數次方的第二個引數值。 | 
| Int/Decimal/String | Int/Decimal/String | Decimal (使用雙精度)，第一個引數次方的第二個引數值。任何轉換為小數的字串。如果任何 String 無法轉換為 Decimal，則結果為 Undefined。 | 
| 其他值 | 其他值 | Undefined. | 

## principal()
<a name="iot-sql-function-principal"></a>

根據發佈觸發訊息的方式，傳回裝置用於身分驗證的委託人。下表說明為各發佈方法和通訊協定傳回的委託人。


****  

| 訊息發佈方式 | 通訊協定 | 憑證類型 | Principal | 
| --- | --- | --- | --- | 
| MQTT 用戶端 | MQTT | X.509 裝置憑證 | X.509 憑證指紋 | 
| AWS IoT 主控台 MQTT 用戶端 | MQTT | IAM 使用者或角色 | iam-role-id:session-name | 
| AWS CLI | HTTP | IAM 使用者或角色 | userid | 
| AWS IoT 裝置 SDK | MQTT | X.509 裝置憑證 | X.509 憑證指紋 | 
| AWS IoT 裝置 SDK | MQTT over WebSocket | IAM 使用者或角色 | userid | 

以下範例顯示 `principal()` 可以傳回哪些不同類型的值：
+ X.509 憑證指紋：`ba67293af50bf2506f5f93469686da660c7c844e7b3950bfb16813e0d31e9373`
+ IAM 角色 ID 和工作階段名稱：`ABCD1EFG3HIJK2LMNOP5:my-session-name`
+ 傳回使用者 ID：`ABCD1EFG3HIJK2LMNOP5`

## rand()
<a name="iot-sql-function-rand"></a>

傳回虛擬亂數，平均分散在 0.0 和 1.0。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`rand()` = 0.8231909191640703

## regexp\$1matches(String, String)
<a name="iot-func-regex-matches"></a>

如果字串 (第一個引數) 包含規則表達式的相符項目 (第二個引數)，則傳回 true。如果您在規則表達式`|`中使用 ，請搭配 使用`()`。

範例：

`regexp_matches("aaaa", "a{2,}") ` = true。

`regexp_matches("aaaa", "b")` = false。

`regexp_matches("aaa", "(aaa|bbb)") ` = true。

`regexp_matches("bbb", "(aaa|bbb)") ` = true。

`regexp_matches("ccc", "(aaa|bbb)") ` = false。


**第一個引數：**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Int 的 String 顯示方式。 | 
| Decimal | Decimal 的 String 顯示方式。 | 
| Boolean | 布林值 (「true」或「false」) 的 String 顯示方式。 | 
| String | String。 | 
| 陣列 | Array (使用標準轉換規則) 的 String 顯示方式。 | 
| 物件 | Object (使用標準轉換規則) 的 String 顯示方式。 | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

*第二個引數：*

必須為有效的 regex 表達式。非字串類型都會使用標準轉換規則轉換為 `String`。根據類型，結果字串可能不是有效的正規運算式。如果 (轉換的) 引數並非有效的 regex 值，結果會為 `Undefined`。

## regexp\$1replace(String, String, String)
<a name="iot-func-regex-replace"></a>

以第三個引數取代所有在第一個引數中出現的第二個參數 (一般表達式)。請以「\$1」參考擷取群組。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`regexp_replace("abcd", "bc", "x")` = "axd"。

`regexp_replace("abcd", "b(.*)d", "$1")` = "ac"。


**第一個引數：**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Int 的 String 顯示方式。 | 
| Decimal | Decimal 的 String 顯示方式。 | 
| Boolean | 布林值 (「true」或「false」) 的 String 顯示方式。 | 
| String | 來源值。 | 
| 陣列 | Array (使用標準轉換規則) 的 String 顯示方式。 | 
| 物件 | Object (使用標準轉換規則) 的 String 顯示方式。 | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

*第二個引數：*

必須為有效的 regex 表達式。非字串類型都會使用標準轉換規則轉換為 `String`。根據類型，結果字串可能不是有效的正規運算式。如果 (轉換的) 引數並非有效的 regex 表達式，則結果為 `Undefined`。

*第三個引數：*

必須為有效的 regex 替換字串。(可以參考擷取群組)。非字串類型都會使用標準轉換規則轉換為 `String`。如果 (轉換的) 引數並非有效的 regex 替換字串，則結果為 `Undefined`。

## regexp\$1substr(String, String)
<a name="iot-func-regex-substr"></a>

在第一個參數中尋找第一個符合第二個參數 (regex) 的值。請以「\$1」參考擷取群組。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`regexp_substr("hihihello", "hi")` = "hi"

`regexp_substr("hihihello", "(hi)*")` = "hihi"


**第一個引數：**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Int 的 String 顯示方式。 | 
| Decimal | Decimal 的 String 顯示方式。 | 
| Boolean | 布林值 (「true」或「false」) 的 String 顯示方式。 | 
| String | String 引數。 | 
| 陣列 | Array (使用標準轉換規則) 的 String 顯示方式。 | 
| 物件 | Object (使用標準轉換規則) 的 String 顯示方式。 | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

*第二個引數：*

必須為有效的 regex 表達式。非字串類型都會使用標準轉換規則轉換為 `String`。根據類型，結果字串可能不是有效的正規運算式。如果 (轉換的) 引數並非有效的 regex 表達式，則結果為 `Undefined`。

## remainder(Decimal, Decimal)
<a name="iot-func-remainder"></a>

傳回第一個引數除以第二的引數的餘數。等同於 [mod(Decimal, Decimal)](#iot-func-mod)。也可以使用「%」當做同樣的模除功能的 infix 運算子。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`remainder(8, 3)` = 2。


****  

| 左運算元 | 右運算元 | Output | 
| --- | --- | --- | 
| Int | Int | Int，第一個引數模除第二個引數。 | 
| Int/Decimal | Int/Decimal | Decimal，第一個引數模除第二個運算元。 | 
| String/Int/Decimal | String/Int/Decimal | 如果所有的字串都轉換為小數，該結果是第一個引數以第二個引數為模。否則為 Undefined。 | 
| 其他值 | 其他值 | Undefined. | 

## replace(String, String, String)
<a name="iot-func-replace"></a>

以第三個引數取代所有在第一個引數中出現的第二個引數。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`replace("abcd", "bc", "x")` = `"axd"`.

`replace("abcdabcd", "b", "x")` = `"axcdaxcd"`.


**所有引數**  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Int 的 String 顯示方式。 | 
| Decimal | Decimal 的 String 顯示方式。 | 
| Boolean | 布林值 (「true」或「false」) 的 String 顯示方式。 | 
| String | 來源值。 | 
| 陣列 | Array (使用標準轉換規則) 的 String 顯示方式。 | 
| 物件 | Object (使用標準轉換規則) 的 String 顯示方式。 | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## rpad(String, Int)
<a name="iot-func-rpad"></a>

傳回字串引數，右側填入第二個引數所指定的空格數。`Int` 引數必須介於 0 到 1000 之間。如果提供的值超出此有效範圍，則引數將設為最接近的有效值 (0 或 1000)。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`rpad("hello", 2)` = "`hello  `".

`rpad(1, 3)` = "`1   `".


****  

| 引數類型 1 | 引數類型 2 | 結果 | 
| --- | --- | --- | 
| String | Int | String 在右側填入，且空格數量等同所給的 Int。 | 
| String | Decimal | Decimal 引數會無條件捨去至最接近的 Int，並且該字串將以提供的 Int 相同的空格數填入右側。 | 
| String | String | 第二個引數將轉換為 Decimal，並無條件捨去至最接近的 Int。String 在右側填入，且空格數量等同 Int 的值。 | 
| 其他值 | Int/Decimal/String | 第一個值會使用標準轉換來轉換為 String，而 rpad 函數將套用到該 String 上。如果其無法轉換，則結果為 Undefined。 | 
| 任何值 | 其他值 | Undefined. | 

## round(Decimal)
<a name="iot-func-round"></a>

將指定的 `Decimal` 無條件進位至最接近的 `Int`。如果 `Decimal` 與兩個 `Int` 值 (例如，0.5) 等距，則 `Decimal` 會無條件進位。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`Round(1.2)` = 1。

`Round(1.5)` = 2。

`Round(1.7)` = 2。

`Round(-1.1)` = -1。

`Round(-1.5)` = -2。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int |  引數。 | 
| Decimal | Decimal 是要向下捨入到最接近的 Int。 | 
| String | Decimal 是要向下捨入到最接近的 Int。如果字串無法轉換為 Decimal，則結果為 Undefined。 | 
| 其他值 | Undefined. | 

## rtrim(String)
<a name="iot-func-rtrim"></a>

移除所給的 `String` 後方所有空格 (tab 與空格)。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`rtrim(" h i ")` = " h i"


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Int 的 String 顯示方式。 | 
| Decimal | Decimal 的 String 顯示方式。 | 
| Boolean | 布林值 (「true」或「false」) 的 String 顯示方式。 | 
| 陣列 | Array (使用標準轉換規則) 的 String 顯示方式。 | 
| 物件 | Object (使用標準轉換規則) 的 String 顯示方式。 | 
| Null | Undefined. | 
| 未定義 | Undefined | 

## sign(Decimal)
<a name="iot-func-sign"></a>

傳回所給數字的符號。當引數的符號為正值時，傳回 1。當引數的符號為負值時，傳回 -1。如果引數為 0，傳回 0。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`sign(-7)` = -1。

`sign(0)` = 0。

`sign(13)` = 1。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Int，Int 值的符號。 | 
| Decimal | Int，Decimal 值的符號。 | 
| String | Int，Decimal 值的符號。此字串會轉換為 Decimal 值，並傳回 Decimal 值的符號。如果 String 無法轉換為 Decimal，則結果為 Undefined。受 SQL 版本 2015-10-08 和更新版本支援。 | 
| 其他值 | Undefined. | 

## sin(Decimal)
<a name="iot-func-sin"></a>

以弧度傳回數字的正弦值。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`sin(0)` = 0.0


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，引數的正弦值。 | 
| Decimal | Decimal (使用雙精度)，引數的正弦值。 | 
| Boolean | Undefined. | 
| String | Decimal (使用雙精度)，引數的正弦值。如果字串無法轉換為 Decimal，則結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| Undefined | Undefined. | 

## sinh(Decimal)
<a name="iot-func-sinh"></a>

以弧度傳回數字的雙曲正弦值。`Decimal` 值在套用函數前會四捨五入至雙精度。結果為雙精度的 `Decimal` 值。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`sinh(2.3)` = 4.936961805545957


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，引數的雙曲正弦值。 | 
| Decimal | Decimal (使用雙精度)，引數的雙曲正弦值。 | 
| Boolean | Undefined. | 
| String | Decimal (使用雙精度)，引數的雙曲正弦值。如果字串無法轉換為 Decimal，則結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## sourceip()
<a name="iot-function-sourceip"></a>

擷取裝置或與其連線之路由器的 IP 地址。如果您的裝置直接連線至網際網路，則此函數會傳回裝置的來源 IP 地址。如果您的裝置是連線到連線網際網路的路由器，則此函數會傳回路由器的來源 IP 地址。SQL 2016-03-23 版可支援。`sourceip()` 不會採用任何參數。

**重要**  
裝置的公有來源 IP 地址通常是最後一個網路位址轉譯 (NAT) 閘道的 IP 地址，例如，您的網際網路服務供應商的路由器或有線數據機。

範例：

`sourceip()="192.158.1.38"`

`sourceip()="1.102.103.104"`

`sourceip()="2001:db8:ff00::12ab:34cd"`

SQL 範例：

`SELECT *, sourceip() as deviceIp FROM 'some/topic'`

如何在 AWS IoT Core 規則動作中使用 sourceip() 函數的範例：

**範例 1**

下列範例顯示如何在 [DynamoDB 動作](https://docs.aws.amazon.com//iot/latest/developerguide/dynamodb-rule-action.html)中呼叫 () 函數作為[替換範本](https://docs.aws.amazon.com//iot/latest/developerguide/iot-substitution-templates.html)。

```
{
	"topicRulePayload": {
		"sql": "SELECT * AS message FROM 'some/topic'",
		"ruleDisabled": false,
		"awsIotSqlVersion": "2016-03-23",
		"actions": [
			{
				"dynamoDB": {
					"tableName": "my_ddb_table",
					"hashKeyField": "key",
					"hashKeyValue": "${sourceip()}",
					"rangeKeyField": "timestamp",
					"rangeKeyValue": "${timestamp()}",
					"roleArn": "arn:aws:iam::123456789012:role/aws_iot_dynamoDB"
				}
			}
		]
	}
}
```

**範例 2**

下列範例顯示如何使用[替換範本](https://docs.aws.amazon.com//iot/latest/developerguide/iot-substitution-templates.html)新增 sourceip() 函數作為 MQTT 使用者屬性。

```
{
	"topicRulePayload": {
		"sql": "SELECT * FROM 'some/topic'",
		"ruleDisabled": false,
		"awsIotSqlVersion": "2016-03-23",
		"actions": [
			{
				"republish": {
					"topic": "${topic()}/republish",
					"roleArn": "arn:aws:iam::123456789012:role/aws_iot_republish",
					"headers": {
						"payloadFormatIndicator": "UTF8_DATA",
						"contentType": "rule/contentType",
						"correlationData": "cnVsZSBjb3JyZWxhdGlvbiBkYXRh",
						"userProperties": [
							{
								"key": "ruleKey1",
								"value": "ruleValue1"
							},
							{
								"key": "sourceip",
								"value": "${sourceip()}"
							}
						]
					}
				}
			}
		]
	}
}
```

您可以從訊息中介裝置和[基本擷取](https://docs.aws.amazon.com//iot/latest/developerguide/iot-basic-ingest.html)路徑傳遞至 AWS IoT Core 規則的訊息中擷取來源 IP 地址。您也可以擷取 IPv4 和 IPv6 訊息的來源 IP。來源 IP 顯示如下：

IPv6：`yyyy:yyyy:yyyy::yyyy:yyyy`

IPv4：`xxx.xxx.xxx.xxx`

**注意**  
原始來源 IP 不會透過[重新發布動作](republish-rule-action.md)傳遞。

## substring(String, Int[, Int])
<a name="iot-func-substring"></a>

預期 `String` 後有一或兩個 `Int` 值。若為 `String` 和單個 `Int` 引數，此函數會從所給的 `String` 索引 (從 0 開始，包含 0) 到 `Int` 的結尾傳回所給的 `String` 的子字串。若為 `String` 和兩個 `Int` 引數，該函數會傳回從第一個 `String` 索引引數 (從 0 開始，包含 0) 到第二個 `Int` 索引引數 (從 0 開始，不含 0) 所提供的所給 `Int` 的子字串。少於零的索引將設為零。比 `String` 長度還長的索引會設為 `String` 長度。至於第三個引數版本，如果第一個索引大於 (或等於) 第二個索引，則結果為空的 `String`。

 如果提供的引數不是 (*字串*、*整數*) 或 (*字串*、*整數*、*整數)*，則標準轉換會套用至該引數，以嘗試將那些引數轉換為正確類型。如果類型無法轉換，函數的結果即為 `Undefined`。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`substring("012345", 0)` = "012345"。

`substring("012345", 2)` = "2345"。

`substring("012345", 2.745)` = "2345"。

`substring(123, 2)` = "3"。

`substring("012345", -1)` = "012345"。

`substring(true, 1.2)` = "true"。

`substring(false, -2.411E247)` = "false"。

`substring("012345", 1, 3)` = "12"。

`substring("012345", -50, 50)` = "012345"。

`substring("012345", 3, 1)` = "".

## sql\$1version()
<a name="iot-sql-function-sql-version"></a>

傳回此規則中指定的 SQL 版本。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`sql_version()` = "2016-03-23"

## sqrt(Decimal)
<a name="iot-func-sqrt"></a>

傳回數字的平方根。`Decimal` 引數在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`sqrt(9)` = 3.0。


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | 引數的平方根。 | 
| Decimal | 引數的平方根。 | 
| Boolean | Undefined. | 
| String | 引數的平方根。如果字串無法轉換為 Decimal，則結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## startswith(String, String)
<a name="iot-func-startswith"></a>

傳回 `Boolean`，無論第一個字串引數的開頭是否為第二個引數。如果引數為 `Null` 或 `Undefined`，則結果為 `Undefined`。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`startswith("ranger","ran")` = true


****  

| 引數類型 1 | 引數類型 2 | 結果 | 
| --- | --- | --- | 
| String | String | 無論第一個字串的開頭是否為第二個字串。 | 
| 其他值 | 其他值 | 所有引數都將使用標準轉換規則轉換為字串。如果第一個字串的開頭是第二個字串，則傳回 true。如果引數為 Null 或 Undefined，則結果為 Undefined。 | 

## tan(Decimal)
<a name="iot-func-tan"></a>

以弧度傳回數字的正切值。`Decimal` 值在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`tan(3)` = -0.1425465430742778


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，引數的正切值。 | 
| Decimal | Decimal (使用雙精度)，引數的正切值。 | 
| Boolean | Undefined. | 
| String | Decimal (使用雙精度)，引數的正切值。如果字串無法轉換為 Decimal，則結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## tanh(Decimal)
<a name="iot-func-tanh"></a>

以弧度傳回數字的雙曲正切值。`Decimal` 值在套用函數前會四捨五入至雙精度。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`tanh(2.3)` = 0.9800963962661914


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | Decimal (使用雙精度)，引數的雙曲正切值。 | 
| Decimal | Decimal (使用雙精度)，引數的雙曲正切值。 | 
| Boolean | Undefined. | 
| String | Decimal (使用雙精度)，引數的雙曲正切值。如果字串無法轉換為 Decimal，則結果為 Undefined。 | 
| Array | Undefined. | 
| 物件 | Undefined. | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## time\$1to\$1epoch(String, String)
<a name="iot-sql-function-time-to-epoch"></a>

使用 `time_to_epoch` 函數將時間戳字串轉換為 Unix epoch 時間中的毫秒數。受 SQL 版本 2016-03-23 和更新版本支援。若要將毫秒轉換為格式化的時間戳記字串，請參閱 [parse\$1time(String, Long[, String])](#iot-sql-function-parse-time)。

`time_to_epoch` 函數預期下列引數：

timestamp  
(字串) 自 Unix epoch 起要轉換為毫秒的時間戳記字串。如果時間戳記字串未指定時區，函數會使用 UTC 時區。

pattern  
(字串) 遵循 [JDK11 時間格式](http://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html)的日期/時間模式。

範例：

`time_to_epoch("2020-04-03 09:45:18 UTC+01:00", "yyyy-MM-dd HH:mm:ss VV")` = 1585903518000

`time_to_epoch("18 December 2015", "dd MMMM yyyy")` = 1450396800000

`time_to_epoch("2007-12-03 10:15:30.592 America/Los_Angeles", "yyyy-MM-dd HH:mm:ss.SSS z")` = 1196705730592

## timestamp()
<a name="iot-function-timestamp"></a>

傳回從 1970 年 1 月 1 日星期四 00：00：00 國際標準時間 (UTC) 開始的目前時間戳記，如 AWS IoT 規則引擎所觀察。受 SQL 版本 2015-10-08 和更新版本支援。

範例：`timestamp()` = `1481825251155`

## topic(Decimal)
<a name="iot-function-topic"></a>

傳回觸發該規則的訊息要傳送至的主題。如果未指定參數，則傳回整個主題。`Decimal` 參數用於指定特定主題區段，並會使用 1 指定第一個區段。對於 topic `foo/bar/baz`，topic(1) 會傳回 `foo`，topic(2) 會傳回 `bar`，依此類推。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`topic()` = "things/myThings/thingOne"

`topic(1)` = "things"

使用[基本擷取](iot-basic-ingest.md)時，topic() 函數無法使用主題的初始字首 (`$aws/rules/rule-name`)。例如，假定主題為：

`$aws/rules/BuildingManager/Buildings/Building5/Floor2/Room201/Lights`

`topic()` = "Buildings/Building5/Floor2/Room201/Lights"

`topic(3)` = "Floor2"

## traceid()
<a name="iot-sql-function-traceid"></a>

傳回 MQTT 的追蹤 ID (UUID)，如果訊息不是透過 MQTT 傳送，則為 `Undefined`。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`traceid() ` = "12345678-1234-1234-1234-123456789012"

## transform(String, Object, Array)
<a name="iot-func-transform"></a>

傳回物件的陣列，其中包含 `Array` 參數上 `Object` 參數的所指定轉換結果。

受 SQL 版本 2016-03-23 和更新版本支援。

String  
要使用的轉換模式。請參閱下表以取得支援的轉換模式，以及了解它們如何從 `Object` 和 `Array` 參數建立 `Result`。

物件  
包含要套用至每個 `Array` 元素之屬性的物件。

陣列  
`Object` 屬性套用至其中的物件陣列。  
此陣列中的每個物件都對應於函數回應中的物件。函數回應中的每個物件都包含存在於原始物件的屬性，以及 `Object` 所提供的屬性，這是由 `String` 中指定的轉換模式所決定。


| `String` 參數 | `Object` 參數 | `Array` 參數 | 結果 | 
| --- | --- | --- | --- | 
| `enrichArray` | 物件 | 物件的陣列 | 物件的陣列，其中每個物件都包含來自 `Array` 參數的元素屬性，以及 `Object` 參數的屬性。 | 
| 任何其他值 | 任何值 | 任何值 | 未定義 | 

**注意**  
此函數傳回的陣列限制為 128 KiB。

### 轉換函數範例 1
<a name="iot-func-transform-example1"></a>

此範例顯示 **transform()** 函數如何從一個資料物件和一個陣列產生單一物件陣列。

在此範例中，下列訊息會發佈至 MQTT 主題 `A/B`。

```
{
    "attributes": {
        "data1": 1,
        "data2": 2
    },
    "values": [
        {
            "a": 3
        },
        {
            "b": 4
        },
        {
            "c": 5
        }
    ]
}
```

主題規則動作的這個 SQL 陳述式會使用 **transform()** 函數與 `enrichArray` 的 `String` 值搭配。在此範例中，`Object` 是來自訊息承載的 `attributes` 屬性，而 `Array` 是 `values` 陣列，其中包含三個物件。

```
select value transform("enrichArray", attributes, values) from 'A/B'
```

在收到訊息承載時，SQL 陳述式會評估為下列回應。

```
[
  {
    "a": 3,
    "data1": 1,
    "data2": 2
  },
  {
    "b": 4,
    "data1": 1,
    "data2": 2
  },
  {
    "c": 5,
    "data1": 1,
    "data2": 2
  }
]
```

### 轉換函數範例 2
<a name="iot-func-transform-example2"></a>

此範例顯示 **transform()** 函數如何使用文字值，以包含並重新命名來自訊息承載的個別屬性。

在此範例中，下列訊息會發佈至 MQTT 主題 `A/B`。這是用於 [轉換函數範例 1](#iot-func-transform-example1) 的同一則訊息。

```
{
    "attributes": {
        "data1": 1,
        "data2": 2
    },
    "values": [
        {
            "a": 3
        },
        {
            "b": 4
        },
        {
            "c": 5
        }
    ]
}
```

主題規則動作的這個 SQL 陳述式會使用 **transform()** 函數與 `enrichArray` 的 `String` 值搭配。**transform()** 函數中的 `Object` 在訊息承載中有一個名為 `key` 且值為 `attributes.data1` 的單一屬性，而 `Array` 是 `values` 陣列，其中包含上述範例中使用的三個物件。

```
select value transform("enrichArray", {"key": attributes.data1}, values) from 'A/B'
```

在收到訊息承載時，此 SQL 陳述式會評估為下列回應。請注意，`data1` 屬性在回應中名為 `key`。

```
[
  {
    "a": 3,
    "key": 1
  },
  {
    "b": 4,
    "key": 1
  },
  {
    "c": 5,
    "key": 1
  }
]
```

### 轉換函數範例 3
<a name="iot-func-transform-example3"></a>

此範例顯示 **transform()** 函數如何用於巢狀 SELECT 子句中，以選取多個屬性並建立新的物件，以供後續處理。

在此範例中，下列訊息會發佈至 MQTT 主題 `A/B`。

```
{
  "data1": "example",
  "data2": {
    "a": "first attribute",
    "b": "second attribute",
    "c": [
      {
        "x": {
          "someInt": 5,
          "someString": "hello"
        },
        "y": true
      },
      {
        "x": {
          "someInt": 10,
          "someString": "world"
        },
        "y": false
      }
    ]
  }
}
```

此轉換函數的 `Object` 是 SELECT 陳述式傳回的物件，其中包含訊息 `data2` 物件的 `a` 和 `b` 元素。`Array` 參數由來自原始訊息中 `data2.c` 陣列的兩個物件組成。

```
select value transform('enrichArray', (select a, b from data2), (select value c from data2)) from 'A/B'
```

在收到上述訊息時，SQL 陳述式會評估為下列回應。

```
[
  {
    "x": {
      "someInt": 5,
      "someString": "hello"
    },
    "y": true,
    "a": "first attribute",
    "b": "second attribute"
  },
  {
    "x": {
      "someInt": 10,
      "someString": "world"
    },
    "y": false,
    "a": "first attribute",
    "b": "second attribute"
  }
]
```

 此回應中傳回的陣列可與支援 `batchMode` 的主題規則動作搭配使用。

## trim(String)
<a name="iot-func-trim"></a>

移除所給的 `String` 前方和後方所有空格。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`Trim(" hi ") ` = "hi"


****  

| 引數類型 | 結果 | 
| --- | --- | 
| Int | 移除 Int 前方和後方所有空格的 String 顯示方式。 | 
| Decimal | 移除 Decimal 前方和後方所有空格的 String 顯示方式。 | 
| Boolean | 移除 Boolean (「true」或「false」) 前方和後方所有空格的 String 顯示方式。 | 
| String | 移除前方和後方所有空格的 String。 | 
| 陣列 | Array (使用標準轉換規則) 的 String 顯示方式。 | 
| 物件 | Object (使用標準轉換規則) 的 String 顯示方式。 | 
| Null | Undefined. | 
| 未定義 | Undefined. | 

## trunc(Decimal, Int)
<a name="iot-func-trunc"></a>

將第一個引數截為第二的引數所指定的 `Decimal` 位數。若第二個引數少於零，則它會設為零。若第二個引數大於 34，則它會設為 34。結果的結尾去掉了零。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`trunc(2.3, 0)` = 2。

`trunc(2.3123, 2)` = 2.31。

`trunc(2.888, 2)` = 2.88。

`trunc(2.00, 5)` = 2。


****  

| 引數類型 1 | 引數類型 2 | 結果 | 
| --- | --- | --- | 
| Int | Int | 來源值。 | 
| Int/Decimal | Int/Decimal | 第一個引數會截短為第二個引數所指定的長度。第二個引數如果不是 Int，則會無條件捨去至最接近的 Int。 | 
| Int/Decimal/String | Int/Decimal | 第一個引數會截短為第二個引數所指定的長度。第二個引數如果不是 Int，則會無條件捨去至最接近的 Int。String 會轉換為 Decimal 值。如果字串轉換失敗，則結果為 Undefined。 | 
| 其他值 |  | Undefined. | 

## upper(String)
<a name="iot-sql-function-upper"></a>

傳回大寫版本的特定 `String`。非 `String` 引數都會使用標準轉換規則轉換為 `String`。受 SQL 版本 2015-10-08 和更新版本支援。

範例：

`upper("hello")` = "HELLO"

`upper(["hello"])` = "[\$1"HELLO\$1"]"

# 文字
<a name="iot-sql-literals"></a>

可以直接在規則 SQL 的 SELECT 和 WHERE 子句中指定文字物件，很適合用於傳遞資訊。

**注意**  
只有在使用 2016-03-23 版本或更高版本的 SQL 時才能使用文字。

會使用 JSON 物件語法 (金鑰/值對，以逗號分隔，索引鍵為字串而值為 JSON 值，以大括號 \$1\$1 括起)。例如：

發佈在主題 `topic/subtopic` 的傳入承載：`{"lat_long": [47.606,-122.332]}`

SQL 陳述式：`SELECT {'latitude': get(lat_long, 0),'longitude':get(lat_long, 1)} as lat_long FROM 'topic/subtopic'`

產生的傳出承載為：`{"lat_long":{"latitude":47.606,"longitude":-122.332}}`。

您也可以直接在規則 SQL 的 SELECT 和 WHERE 子句中指定陣列，即可將資訊分組。會使用 JSON 語法 (將逗號分隔項目用方括號 [] 括起，以建立陣列文字)。例如：

發佈在主題 `topic/subtopic` 的傳入承載：`{"lat": 47.696, "long": -122.332}`

SQL 陳述式：`SELECT [lat,long] as lat_long FROM 'topic/subtopic'`

產生的輸出承載為：`{"lat_long": [47.606,-122.332]}`。

# 案例陳述式
<a name="iot-sql-case"></a>

可用於分支執行的案例陳述式，例如切換陳述式。

語法：

```
CASE v WHEN t[1] THEN r[1] 
  WHEN t[2] THEN r[2] ... 
  WHEN t[n] THEN r[n] 
  ELSE r[e] END
```

表達式 *`v`* 會受到評估並對每個 `WHEN` 子句的 *`t[i]`* 值配對是否相等。如果找到匹配的結果，相對應的 *`r[i]`* 表達式會成為該 `CASE` 陳述式的結果。此 `WHEN` 子句會按順序進行評估，以便如果有多個符合子句，則第一個符合子句的結果會成為 `CASE` 陳述式的結果。如果沒有相符項目，`ELSE` 子句的 *`r[e]`* 即為結果。如果沒有相符項目，也沒有 `ELSE` 子句，則結果即為 `Undefined`。

`CASE` 陳述式會要求至少一個 `WHEN` 子句。`ELSE` 子句是選用的。

例如：

發佈在主題 `topic/subtopic` 的傳入承載：

```
{
    "color":"yellow"
}
```

SQL 陳述式：

```
SELECT CASE color
        WHEN 'green' THEN 'go'
        WHEN 'yellow' THEN 'caution'
        WHEN 'red' THEN 'stop'
        ELSE 'you are not at a stop light' END as instructions
    FROM 'topic/subtopic'
```

產生的輸出承載為：

```
{
    "instructions":"caution"
}
```

**注意**  
如果 *`v`* 是 `Undefined`，則案例陳述式的結果為 `Undefined`。

# JSON Extensions
<a name="iot-sql-json"></a>

您可以使用下列 ANSI SQL 的延伸模組，協助使用巢狀 JSON 物件。

"." 運算子

運算子會存取嵌入式 JSON 物件的成員，功能與 ANSI SQL 和 JavaScript 完全相同。例如：

```
SELECT foo.bar AS bar.baz FROM 'topic/subtopic'
```

從傳送至 `topic/subtopic` 主題的下列訊息承載中選取 `foo` 物件中 `bar` 屬性的值。

```
{
  "foo": {
    "bar": "RED",
    "bar1": "GREEN",
    "bar2": "BLUE"
  }
}
```

如果 JSON 屬性名稱包含連字元或數字字元，「點」標記法將無法運作。您必須改用 [get 函數](iot-sql-functions.md#iot-sql-function-get) 來擷取屬性的值。

 在此範例中，下列訊息會傳送至 `iot/rules` 主題。

```
{
  "mydata": {
    "item2": {
      "0": {
        "my-key": "myValue"
      }
    }
  }
}
```

正常情況下，將識別 `my-key` 的值，如在此查詢中一般。

```
SELECT * from iot/rules WHERE mydata.item2.0.my-key= "myValue"
```

不過，由於屬性名稱 `my-key` 包含連字號，且 `item2` 包含數字字元，所以 [get 函數](iot-sql-functions.md#iot-sql-function-get)必須如下列查詢所示一般使用。

```
SELECT * from 'iot/rules' WHERE get(get(get(mydata,"item2"),"0"),"my-key") = "myValue"
```

`*` 運算子

運作方式與 ANSI SQL 的 `*` 萬用字元相同。此僅會使用在 SELECT 子句，且會建立包含訊息資料的新 JSON 物件。如果訊息承載並非 JSON 格式，`*` 會以原始位元組的形式傳回整個訊息承載。例如：

```
SELECT * FROM 'topic/subtopic'
```

**將函數套用在屬性值上**  
以下為可能為由裝置發佈的範例 JSON 承載：

```
{
    "deviceid" : "iot123",
    "temp" : 54.98,
    "humidity" : 32.43,
    "coords" : {
        "latitude" : 47.615694,
        "longitude" : -122.3359976
    }
}
```

以下範例會將函數套用在 JSON 承載內的屬性值上：

```
SELECT temp, md5(deviceid) AS hashed_id FROM topic/#
```

此次查詢的結果為下列 JSON 物件：

```
{
   "temp": 54.98,
   "hashed_id": "e37f81fb397e595c4aeb5645b8cbbbd1"
}
```

# 替代範本
<a name="iot-substitution-templates"></a>

您可以使用替代範本來擴增觸發規則時傳回的 JSON 資料，並 AWS IoT 執行動作。替代範本的語法是`${`*表達式*`}`，其中*表達式*可以是 SELECT 子句、WHERE 子句和 AWS IoT 中 支援的任何表達式[AWS IoT 規則動作](iot-rule-actions.md)。您可以將此表達式插入規則的動作欄位中，以便動態設定動作。實際上，此功能會取代動作中的資訊片段。這包含了在原始訊息中呈現的函數、運算子和資訊。

**重要**  
因為替換範本中的運算式與「SELECT ...」陳述式是分開計算的，所以不能參考使用 AS 子句建立的別名。您只能參考原始承載、[函數](iot-sql-functions.md)和[運算子](iot-sql-operators.md)中呈現的資訊。

如需支援的表達式的詳細資訊，請參閱 [AWS IoT SQL 參考](iot-sql-reference.md)。

下列規則動作支援替代範本。每個動作都支援可以取代的不同欄位。
+ [Apache Kafka](apache-kafka-rule-action.md)
+ [CloudWatch 警示](cloudwatch-alarms-rule-action.md)
+ [CloudWatch Logs](cloudwatch-logs-rule-action.md)
+ [CloudWatch 指標](cloudwatch-metrics-rule-action.md)
+ [DynamoDB](dynamodb-rule-action.md)
+ [DynamoDBv2](dynamodb-v2-rule-action.md)
+ [Elasticsearch](elasticsearch-rule-action.md)
+ [HTTP](https-rule-action.md)
+ [AWS IoT Events](iotevents-rule-action.md)
+ [AWS IoT SiteWise](iotsitewise-rule-action.md)
+ [Kinesis Data Streams](kinesis-rule-action.md)
+ [Firehose](kinesis-firehose-rule-action.md)
+ [Lambda](lambda-rule-action.md)
+ [Location](location-rule-action.md)
+ [OpenSearch](opensearch-rule-action.md)
+ [重新發佈](republish-rule-action.md)
+ [S3](s3-rule-action.md)
+ [SNS](sns-rule-action.md)
+ [SQS](sqs-rule-action.md)
+ [步驟函數](stepfunctions-rule-action.md)
+ [Timestream](timestream-rule-action.md)

替代範本會顯示在規則內的動作參數中：

```
{
    "sql": "SELECT *, timestamp() AS timestamp FROM 'my/iot/topic'",
    "ruleDisabled": false,
    "actions": [{
        "republish": {
            "topic": "${topic()}/republish",
            "roleArn": "arn:aws:iam::123456789012:role/my-iot-role"
        }
    }]
}
```

如果這個規則是由下列發佈至 `my/iot/topic` 的 JSON 所觸發：

```
{
    "deviceid": "iot123",
    "temp": 54.98,
    "humidity": 32.43,
    "coords": {
        "latitude": 47.615694,
        "longitude": -122.3359976
    }
}
```

然後，此規則會將下列 JSON 發佈至 `my/iot/topic/republish`，以 AWS IoT 取代`${topic()}/republish`：

```
{
    "deviceid": "iot123",
    "temp": 54.98,
    "humidity": 32.43,
    "coords": {
        "latitude": 47.615694,
        "longitude": -122.3359976
    },
    "timestamp": 1579637878451
}
```

# 巢狀物件查詢
<a name="iot-sql-nested-queries"></a>

您可以使用巢狀 SELECT 子句來查詢陣列和內部 JSON 物件中的屬性。受 SQL 版本 2016-03-23 和更新版本支援。

請考慮下列 MQTT 訊息：

```
{ 
    "e": [
        { "n": "temperature", "u": "Cel", "t": 1234, "v": 22.5 },
        { "n": "light", "u": "lm", "t": 1235, "v": 135 },
        { "n": "acidity", "u": "pH", "t": 1235, "v": 7 }
    ]
}
```

**Example**  
您可以使用以下規則將值轉換為新的陣列。  

```
SELECT (SELECT VALUE n FROM e) as sensors FROM 'my/topic'
```

該規則會產生以下輸出。

```
{
    "sensors": [
        "temperature",
        "light",
        "acidity"
    ]
}
```

**Example**  
使用相同的 MQTT 訊息，您也可以使用下列規則查詢巢狀物件中的特定值。  

```
SELECT (SELECT v FROM e WHERE n = 'temperature') as temperature FROM 'my/topic'
```

該規則會產生以下輸出。

```
{
    "temperature": [
        {
            "v": 22.5
        }
    ]
}
```

**Example**  
您也可以使用更複雜的規則來平面化輸出。  

```
SELECT get((SELECT v FROM e WHERE n = 'temperature'), 0).v as temperature FROM 'topic'
```

該規則會產生以下輸出。

```
{
    "temperature": 22.5
}
```

# 使用二進位承載
<a name="binary-payloads"></a>

若要將訊息承載做為原始二進位資料 (而不是 JSON 物件) 處理，可以使用 \$1 運算子在 SELECT 子句中參考它。

**Topics**
+ [

## 二進位承載範例
](#binary-payloads-examples)
+ [

## 對 Protobuf 訊息承載進行解碼
](#binary-payloads-protobuf)

## 二進位承載範例
<a name="binary-payloads-examples"></a>

使用 \$1 參考作為原始二進位資料的訊息承載時，您可以將資料新增至規則。如果您有空白或 JSON 承載，則產生的承載可以使用規則新增資料。下列顯示支援 `SELECT` 子句的範例。
+ 對於二進位承載，您可以使用下方僅具有一個 \$1 的 `SELECT` 子句。
  + 

    ```
    SELECT * FROM 'topic/subtopic'
    ```
  + 

    ```
    SELECT * FROM 'topic/subtopic' WHERE timestamp() % 12 = 0
    ```
+ 您也可以新增資料並使用下方 `SELECT` 子句。
  + 

    ```
    SELECT *, principal() as principal, timestamp() as time FROM 'topic/subtopic'
    ```
  + 

    ```
    SELECT encode(*, 'base64') AS data, timestamp() AS ts FROM 'topic/subtopic'
    ```
+ 您也可以使用這些 `SELECT` 子句搭配二進位承載使用。
  + 下方項目是指 WHERE 子句中的 `device_type`。

    ```
    SELECT * FROM 'topic/subtopic' WHERE device_type = 'thermostat'
    ```
  + 也支援下方項目。

    ```
    {
    	"sql": "SELECT * FROM 'topic/subtopic'",
    	"actions": [
    		{
    			"republish": {
    				"topic": "device/${device_id}"
    			}
    		}
    	]
    }
    ```

下方規則動作不支援二進位承載，因此您必須將它們解碼。
+ 對於某些不支援二進位承載輸入 (例如 [Lambda 動作](https://docs.aws.amazon.com/iot/latest/developerguide/iot-rule-actions.html#lambda-rule)) 的規則，您必須解碼二進位承載。如果 Lambda 規則動作是 base64 編碼且在 JSON 承載中，則可以接收二進位資料。您可以將規則變更如下，以此執行此項操作。

  ```
  SELECT encode(*, 'base64') AS data FROM 'my_topic'
  ```
+ SQL 陳述式不支援將字串作為輸入。若要將字串輸入轉換為 JSON，您可以執行下列命令。

  ```
  SELECT decode(encode(*, 'base64'), 'base64') AS payload FROM 'topic'
  ```

## 對 Protobuf 訊息承載進行解碼
<a name="binary-payloads-protobuf"></a>

[協定緩衝區（protobuf）](https://developers.google.com/protocol-buffers)是一種開放原始碼資料格式，用於將結構化資料序列化為壓縮二進位形式。其可用於透過網路傳輸資料或將其儲存在檔案中。Protobuf 可讓您以小封包大小並以比其他簡訊格式更快的速度傳送資料。 AWS IoT Core Rules 支援 protobuf，方法是提供 [decode(value， decodingScheme)](iot-sql-functions.md#iot-sql-decode-base64) SQL 函數，這可讓您將 protobuf 編碼的訊息承載解碼為 JSON 格式，並將其路由至下游服務。本節詳細介紹在 AWS IoT Core 規則中設定 protobuf 解碼的逐步流程。

**Topics**
+ [

### 先決條件
](#binary-payloads-protobuf-prerequisites)
+ [

### 建立描述項檔案
](#binary-payloads-protobuf-descriptor-steps)
+ [

### 將描述項檔案上傳至 S3 儲存貯體
](#binary-payloads-protobuf-s3-steps)
+ [

### 在規則中設定 protobuf 解碼
](#binary-payloads-protobuf-steps)
+ [

### 限制
](#binary-payloads-protobuf-limitations)
+ [

### 最佳實務
](#binary-payloads-protobuf-bestpractices)

### 先決條件
<a name="binary-payloads-protobuf-prerequisites"></a>
+ [協定緩衝區 (protobuf)](https://developers.google.com/protocol-buffers) 的基本知識
+ 該[`.proto` 檔案](https://developers.google.com/protocol-buffers/docs/proto3)定義了訊息類型及相關的相依性
+ 在您的系統上安裝 [Protobuf 編譯器 (protoc)](https://github.com/protocolbuffers/protobuf/releases)

### 建立描述項檔案
<a name="binary-payloads-protobuf-descriptor-steps"></a>

如果您已有描述項檔案，則可以略過此步驟。描述項檔案 (`.desc`) 是 `.proto` 檔案的編譯版本，屬於文字檔案，用於定義在 protobuf 序列化中使用的資料結構和訊息類型。要產生描述項檔案，您必須定義 `.proto` 檔案並使用 [protoc](https://github.com/protocolbuffers/protobuf/releases) 編譯器對其進行編譯。

1. 建立用於定義訊息類型的 `.proto` 檔案。範例 `.proto` 檔案看起來可能與以下內容相似：

   ```
   syntax = "proto3";
   
   message Person {
     optional string name = 1;
     optional int32 id = 2;
     optional string email = 3;
   }
   ```

   在此範例 `.proto` 檔案中，您使用 proto3 語法並定義訊息類型 `Person`。`Person` 訊息定義會指定三個欄位 (名稱、ID 和電子郵件)。如需有關 `.proto` 檔案訊息格式的詳細資訊，請參閱 [語言指南 (proto3)](https://developers.google.com/protocol-buffers/docs/proto3)。

1. 使用 [protoc](https://github.com/protocolbuffers/protobuf/releases) 編譯器編譯 `.proto` 檔案並產生描述項檔案。用於建立描述項 (`.desc`) 檔案的範例命令如下所示：

   ```
   protoc --descriptor_set_out=<FILENAME>.desc \
       --proto_path=<PATH_TO_IMPORTS_DIRECTORY> \
       --include_imports \
       <PROTO_FILENAME>.proto
   ```

   此範例命令會產生描述項檔案 `<FILENAME>.desc`， AWS IoT Core 規則可用來解碼符合 中定義之資料結構的 protobuf 承載`<PROTO_FILENAME>.proto`。
   + `--descriptor_set_out`

     指定所要產生的描述項檔案 (`<FILENAME>.desc`) 名稱。
   + `--proto_path`

     指定編譯檔案所參考的任何已匯入 `.proto` 檔案的位置。如果您有多項已匯入的 `.proto` 檔案位於不同位置，則可以多次指定旗標。
   + `--include_imports`

     指定任何已匯入的 `.proto` 檔案也應加以編譯，並納入 `<FILENAME>.desc` 描述項檔案中。
   + `<PROTO_FILENAME>.proto`

     指定要編譯的 `.proto` 檔案名稱。

   如需 protoc 參考的詳細資訊，請參閱 [API 參考](https://developers.google.com/protocol-buffers/docs/reference/overview)。

### 將描述項檔案上傳至 S3 儲存貯體
<a name="binary-payloads-protobuf-s3-steps"></a>

建立描述項檔案 之後`<FILENAME>.desc`，請使用 AWS API、 AWS SDK 或 將描述項檔案上傳至 Amazon S3 `<FILENAME>.desc`儲存貯體 AWS 管理主控台。

**重要考量**
+ 請確定您上傳描述項檔案到 中 Amazon S3 儲存貯 AWS 帳戶 體的 ，與您打算設定規則 AWS 區域 的位置相同。
+ 請務必授予`FileDescriptorSet`從 S3 讀取 的 AWS IoT Core 存取權。如果 S3 儲存貯體已停用伺服器端的加密 (SSE)，或者 S3 儲存貯體是使用 Amazon S3 受管金鑰 (SSE-S3) 進行加密，則不需要其他政策組態。下列範例儲存貯體政策可實現此目的：  
****  

  ```
  {
  	"Version":"2012-10-17",		 	 	 
  	"Statement": [
  		{
  			"Sid": "Statement1",
  			"Effect": "Allow",
  			"Principal": {
  				"Service": "iot.amazonaws.com"
  			},
  			"Action": "s3:Get*",
                        "Resource": "arn:aws:s3:::<BUCKET NAME>/<FILENAME>.desc"
  		}
  	]
  }
  ```
+ 如果您的 S3 儲存貯體使用 AWS Key Management Service 金鑰 (SSE-KMS) 加密，請務必在存取 S3 儲存貯體時授予使用金鑰的 AWS IoT Core 許可。作法為您可以將下列陳述式新增至金鑰政策：

  ```
  {
  	"Sid": "Statement1",
  	"Effect": "Allow",
  	"Principal": {
  		"Service": "iot.amazonaws.com"
  	},
  	"Action": [
  		"kms:Decrypt",
  		"kms:GenerateDataKey*",
  		"kms:DescribeKey"
  	],
          "Resource": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
  	
  }
  ```

### 在規則中設定 protobuf 解碼
<a name="binary-payloads-protobuf-steps"></a>

將描述項檔案上傳到 Amazon S3 儲存貯體後，請設定一項[規則](https://docs.aws.amazon.com//iot/latest/developerguide/iot-create-rule.html)以供使用 [decode(value, decodingScheme)](iot-sql-functions.md#iot-sql-decode-base64) SQL 函數來解碼 protobuf 訊息承載格式。詳細的函數簽章和範例可參見 *AWS IoT SQL 參考*的 [decode(value, decodingScheme)](iot-sql-functions.md#iot-sql-decode-base64) SQL 函數。

以下是使用 [decode(value, decodingScheme)](iot-sql-functions.md#iot-sql-decode-base64) 函數的 SQL 表達式範例：

```
SELECT VALUE decode(*, 'proto', '<BUCKET NAME>', '<FILENAME>.desc', '<PROTO_FILENAME>', '<PROTO_MESSAGE_TYPE>') FROM '<MY_TOPIC>'
```

在此範例表達式中：
+ 您可以使用 [decode(value, decodingScheme)](iot-sql-functions.md#iot-sql-decode-base64) SQL 函數，來解碼 `*` 參考的二進位訊息承載。這可以是二進位 protobuf 編碼承載，也可以是代表 base64 編碼 protobuf 承載的 JSON 字串。
+ 所提供的訊息承載會使用 `PROTO_FILENAME.proto` 中定義的`Person` 訊息類型進行編碼。
+ 名為 `BUCKET NAME` 的 Amazon S3 儲存貯體含有從 `PROTO_FILENAME.proto` 產生的 `FILENAME.desc`。

完成組態後，請在規則訂閱的主題 AWS IoT Core 上發佈訊息至 。

### 限制
<a name="binary-payloads-protobuf-limitations"></a>

AWS IoT Core 規則支援具有下列限制的 protobuf：
+ 不支援在[替代範本](https://docs.aws.amazon.com//iot/latest/developerguide/iot-substitution-templates.html)中解碼 protobuf 訊息承載。
+ 在解碼 protobuf 訊息承載時，您最多可以在單一 SQL 表達式中使用[解碼 SQL 函數](iot-sql-functions.md#iot-sql-decode-base64) 2 次。
+ 傳入承載大小上限為 128 KiB (1KiB = 1024 位元組)，傳出承載大小上限為 128 KiB，而儲存在 Amazon S3 儲存貯體中的 `FileDescriptorSet` 物件大小上限為 32 KiB。
+ 不支援使用 SSE-C 加密功能對 Amazon S3 儲存貯體進行加密。

### 最佳實務
<a name="binary-payloads-protobuf-bestpractices"></a>

以下是一些最佳實務和疑難排解提示。
+ 在 Amazon S3 儲存貯體中備份原型檔案。

  理想的做法是備份 proto 檔案以防患未然。例如，如果在執行 protoc 時錯誤地修改了沒有備份的原型檔案，這可能會導致生產堆疊發生問題。有多種方法在 Amazon S3 儲存貯體中備份檔案 例如，您可以[在 S3 儲存貯體中使用版本控制](https://docs.aws.amazon.com//AmazonS3/latest/userguide/Versioning.html)。如需有關如何備份 Amazon S3 儲存貯體中檔案的詳細資訊，請參閱 *[Amazon S3 開發人員指南](https://docs.aws.amazon.com//aws-backup/latest/devguide/recovery-points.html)*。
+ 設定 AWS IoT 記錄以檢視日誌項目。

  設定 AWS IoT 記錄是很好的做法，讓您可以在 CloudWatch 中檢查帳戶的 AWS IoT 日誌。當規則的 SQL 查詢呼叫外部 函數時， AWS IoT Core Rules 會產生具有 之 `eventType`的日誌項目`FunctionExecution`，其中包含可協助您對失敗進行疑難排解的原因欄位。可能的錯誤包括找不到 Amazon S3 物件，或是 protobuf 檔案描述項無效。如需進一步了解如何設定 AWS IoT 記錄及查看日誌項目，請參閱[設定 AWS IoT 記錄](https://docs.aws.amazon.com//iot/latest/developerguide/configure-logging.html)和[規則引擎日誌項目](https://docs.aws.amazon.com//iot/latest/developerguide/cwl-format.html#log-rules-fn-exec)。
+ 使用新的物件索引鍵來更新 `FileDescriptorSet` 以及更新規則中的物件索引鍵。

  您可以將更新後的描述項檔案上傳到 Amazon S3 儲存貯體來更新 `FileDescriptorSet`。系統可能需要最多 15 分鐘的時間來反映 `FileDescriptorSet` 的更新作業。為了避免這種延遲，理想做法是使用新的物件索引鍵上傳更新後的 `FileDescriptorSet`，並在規則中更新物件索引鍵。

# SQL 版本
<a name="iot-rule-sql-version"></a>

 AWS IoT 規則引擎使用類似 SQL 的語法，從 MQTT 訊息中選取資料。SQL 陳述式會以指定的 SQL 版本來解釋，版本由描述規則的 JSON 文件的 `awsIotSqlVersion` 屬性指定。如需更多關於 JSON 規則文件結構的資訊，請參閱[建立規則的相關文章](iot-create-rule.md)。`awsIotSqlVersion` 屬性可讓您指定要使用的 AWS IoT SQL 規則引擎版本。部署新版本時，可以繼續使用較早版本，或變更規則以使用新版本。目前的規則會繼續使用建立時使用的版本。

下列 JSON 範例顯示了如何使用 `awsIotSqlVersion` 屬性來指定 SQL 版本。

```
{
    "sql": "expression",
    "ruleDisabled": false,
    "awsIotSqlVersion": "2016-03-23",
    "actions": [{
        "republish": {
            "topic": "my-mqtt-topic",
            "roleArn": "arn:aws:iam::123456789012:role/my-iot-role"
        }
    }]
}
```

AWS IoT 目前支援下列 SQL 版本：
+ `2016-03-23`：建立於 2016 年 3 月 23 日的 SQL 版本（推薦）。
+ `2015-10-08`：建立於 2015 年 10 月 8 日的原始 SQL 版本。
+ `beta`：最新的 SQL 版本。此版本可能導致規則受到中段變更。

## 2016 年 3 月 23 日 SQL 規則引擎版本的新功能
<a name="sql-2016-03-23-beta"></a>
+ 修正巢狀 JSON 物件的選取問題。
+ 修正陣列查詢的問題。
+ 支援物件內部查詢。如需詳細資訊，請參閱[巢狀物件查詢](iot-sql-nested-queries.md)。
+ 支援將陣列輸出為最上層物件。
+ 除了 `encode(value, encodingScheme)` 函數外，它也可以應用於 JSON 和非 JSON 格式資料。如需詳細資訊，請參閱[編碼函數](iot-sql-functions.md#iot-sql-encode-payload)。

### 輸出一個 `Array` 作為最上層物件
<a name="return-array-rule"></a>

此功能可讓規則將陣列作為最上層物件傳回。舉例而言，若為以下的 MQTT 訊息：

```
{
    "a": {"b":"c"},
    "arr":[1,2,3,4]
}
```

此外以下規則：

```
SELECT VALUE arr FROM 'topic'
```

該規則會產生以下輸出。

```
[1,2,3,4]
```