

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 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)、[Case 语句](iot-sql-case.md)、[JSON 扩展](iot-sql-json.md)、、[变量](iot-sql-set.md#iot-sql-set-usage)和[嵌套对象查询](iot-sql-nested-queries.md)。

**SELECT**  
（必填）从传入消息有效载荷提取信息并执行信息转换。要使用的消息由[主题筛选条件](topics.md#topicfilters)在 FROM 子句中指定。  
SELECT 子句支持[数据类型](iot-sql-data-types.md)[运算符](iot-sql-operators.md)[函数](iot-sql-functions.md)、[文本](iot-sql-literals.md)、、[Case 语句](iot-sql-case.md)、[JSON 扩展](iot-sql-json.md)、[替换模板](iot-substitution-templates.md)、、、[嵌套对象查询](iot-sql-nested-queries.md)、[变量](iot-sql-set.md#iot-sql-set-usage)和[二进制有效载荷](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)、[Case 语句](iot-sql-case.md)、、[JSON 扩展](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>

SE AWS IoT LECT 子句与 ANSI SQL SELECT 子句基本相同，但有一些细微的区别。

SELECT 子句支持[数据类型](iot-sql-data-types.md)[运算符](iot-sql-operators.md)[函数](iot-sql-functions.md)、[文本](iot-sql-literals.md)、[Case 语句](iot-sql-case.md)、、[JSON 扩展](iot-sql-json.md)、、[嵌套对象查询](iot-sql-nested-queries.md)、[变量](iot-sql-set.md#iot-sql-set-usage)和[二进制有效载荷](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 扩展](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}`（对于主题/子主题2）和`{t: 60}`（for）的传出有效负载。`{t: 70}` topic/subtopic-3/details它未订阅 `'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)、[Case 语句](iot-sql-case.md)、[JSON 扩展](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>

定义变量后，可以在以下情况下使用它们：
+ 选择子句
+ WHERE 子句
+ 其他 SET 变量赋值
+ 操作替换模板
+ 错误操作替换模板
+ 嵌套的选择查询
+ 函数参数（某些参数，例如 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 扩展](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) 

## 设定条款限制
<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)、[Case 语句](iot-sql-case.md)、、[JSON 扩展](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 有效载荷，发布位置：“topic/subtopic”：“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 尝试解析与正则表达式匹配的字符串:^-?\$1d\$1(\$1.\$1d\$1)?((?i)E-?\$1d\$1)?\$1。可自动转换为 Decimal 的字符串示例包括“0”、“-1.2”、“5E-12”。 | 
| 数组 | Undefined. | 
| 对象 | Undefined. | 
| Null | Null. | 
| 未定义 | Undefined. | 


**To int**  

| 参数类型 | 结果 | 
| --- | --- | 
| Int | 源值。 | 
| Decimal | 源值都舍入到最接近的 Int。 | 
| Boolean | Undefined。（您可以明确使用 cast 函数使 true = 1.0，false = 0.0。) | 
| String |  SQL 引擎尝试将字符串解析为。Decimal AWS IoT 尝试解析与正则表达式匹配的字符串:^-?\$1d\$1(\$1.\$1d\$1)?((?i)E-?\$1d\$1)?\$1。“0”、“-1.2”、“5E-12” 都是自动转换为 Decimal s 的字符串的示例。 AWS IoT 尝试将其转换为 aDecimal，然后将其中的小数位截断String为一个。Decimal Int | 
| 数组 | 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。 | 
| 数组 | Undefined. | 
| 对象 | Undefined. | 
| Null | Undefined. | 
| 未定义 | Undefined. | 


**To string**  

| 参数类型 | 结果 | 
| --- | --- | 
| Int | 标准表示法中 Int 的字符串表示形式。 | 
| Decimal | 科学表示法中 Decimal 值的字符串表示。 | 
| Boolean | “true”或“false”。均为小写。 | 
| String | 原始值。 | 
| 数组 | Array 序列化为 JSON。结果字符串为逗号分隔的列表，括在方括号中。String 带引号。Decimal、Int、Boolean 和 Null 不带引号。 | 
| 对象 | 序列化为 JSON 的对象。结果字符串为键值对的逗号分隔列表，以大括号开头和结束。String 带引号。Decimal、Int、Boolean 和 Null 不带引号。 | 
| Null | Undefined. | 
| 未定义 | Undefined。 | 

# 运算符
<a name="iot-sql-operators"></a>

可以在 SELECT 和 WHERE 子句中使用以下运算符。

## AND 运算符
<a name="iot-sql-operators-and"></a>

返回 `Boolean` 结果。执行逻辑与运算。如果左右操作数为 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` 结果。执行逻辑或运算。如果左右操作数至少有一个为 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` 结果。执行逻辑非运算。如果操作数为 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，因为名为 `arr` 的数组中存在 3 。因此，在 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，因为名为 `arr` 的数组中存在 3 。因此，在 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. | 

## >= operator
<a name="iot-sql-operators-greater-equal"></a>

返回 `Boolean` 结果。如果左侧操作数大于等于右侧操作数，则返回 true。两个操作数将转换为 `Decimal`，然后进行比较。

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


**>= operator**  

| 左侧操作数 | 右侧操作数 | 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` 结果。如果左侧操作数小于右侧操作数，则返回 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-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。的顺序 keys/values 并不重要。 | 
| Null | Null | False。 | 
| 任意值 | Undefined | Undefined。 | 
| 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。的顺序 keys/values 并不重要。 | 
| 任意值 | 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-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。 | 
| 数组 | Undefined. | 
| 对象 | Undefined. | 
| Null | Undefined. | 
| 未定义 | Undefined. | 

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

以 `String` 形式返回拥有该规则的账户的 ID。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。 | 
| 数组 | 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。 | 
| 数组 | 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。 | 
| 数组 | 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。


**参数**  

| 参数 | 说明 | 
| --- | --- | 
| functionArn |  要调用的 Lambda 函数的 ARN。Lambda 函数必须返回 JSON 数据。  | 
| inputJson |  传递到 Lambda 函数的 JSON 输入。要传递嵌套对象查询和文本，您必须使用 SQL 版本 2016-03-23。  | 

您必须授予调用指定的 Lambda 函数的 AWS IoT `lambda:InvokeFunction`权限。以下示例说明如何使用 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`为了 AWS IoT 允许调用 Lambda 函数。

--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` 从在主题“topic/subtopic”上发布的消息中选择数据。

`some.value` 从 Lambda 函数生成的输出中选择数据。

**注意**  
 规则引擎限制 Lambda 函数的执行持续时间。从规则执行的 Lambda 函数调用应在 2000 毫秒内完成。

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

在两个 `Int`（转换成的）参数的位表示之间逐位执行与运算。SQL 版本 2015-10-08 及更高版本支持。

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


****  

| 参数类型 | 参数类型 | 结果 | 
| --- | --- | --- | 
| Int | Int | Int，对两个参数逐位执行与运算。 | 
| Int/Decimal | Int/Decimal | Int，对两个参数逐位执行与运算。所有非 Int 数字向下舍入至最近的 Int。如果任意参数不能转换为 Int，则结果为 Undefined。 | 
| Int/Decimal/String | Int/Decimal/String | Int，对两个参数逐位执行与运算。所有字符串转换为小数并向下舍入至最近的 Int。如果转换失败，结果为 Undefined。 | 
| 其它值 | 其它值 | Undefined. | 

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

在两个参数的位表示之间逐位执行或运算。SQL 版本 2015-10-08 及更高版本支持。

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


****  

| 参数类型 | 参数类型 | 结果 | 
| --- | --- | --- | 
| Int | Int | Int，对两个参数逐位执行或运算。 | 
| Int/Decimal | Int/Decimal | Int，对两个参数逐位执行或运算。所有非 Int 数字向下舍入至最近的 Int。如果转换失败，结果为 Undefined。 | 
| Int/Decimal/String | Int/Decimal/String | Int，对两个参数逐位执行或运算。所有字符串转换为小数并向下舍入至最近的 Int。如果转换失败，结果为 Undefined。 | 
| 其它值 | 其它值 | Undefined. | 

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

在两个 `Int`（转换成的）参数的位表示之间逐位执行异或运算。SQL 版本 2015-10-08 及更高版本支持。

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


****  

| 参数类型 | 参数类型 | 结果 | 
| --- | --- | --- | 
| Int | Int | Int，对两个参数逐位执行异或运算。 | 
| Int/Decimal | Int/Decimal | Int，对两个参数逐位执行异或运算。非 Int 数字向下舍入至最近的 Int。 | 
| Int/Decimal/String | Int/Decimal/String | Int，对两个参数逐位执行异或运算。字符串转换为小数并向下舍入到最近的 Int。如果任何转换失败，结果为 Undefined。 | 
| 其它值 | 其它值 | Undefined. | 

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

对 `Int`（转换成的）参数的位表示逐位执行非运算。SQL 版本 2015-10-08 及更高版本支持。

示例：`bitnot(13)` = 2


****  

| 参数类型 | 结果 | 
| --- | --- | 
| Int | Int，对参数逐位执行非运算。 | 
| Decimal | Int，对参数逐位执行非运算。Decimal 值会向下舍入至最近的 Int。 | 
| String | Int，对参数逐位执行非运算。字符串转换为小数值并向下舍入至最近的 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**  

| Keyword | 结果 | 
| --- | --- | 
| String | 将值强制转换为 String。 | 
| Nvarchar | 将值强制转换为 String。 | 
| 文本 | 将值强制转换为 String。 | 
| Ntext | 将值强制转换为 String。 | 
| varchar | 将值强制转换为 String。 | 
| Int | 将值强制转换为 Int。 | 
| 整数 | 将值强制转换为 Int。 | 
| 双精度 | 将值强制转换为 Decimal（双精度）。 | 


**此外，对于 SQL 版本 2016-03-23**  

| Keyword | 结果 | 
| --- | --- | 
| Decimal | 将值强制转换为 Decimal。 | 
| 布尔型 | 将值强制转换为 Boolean。 | 
| Boolean | 将值强制转换为 Boolean。 | 

强制转换规则：


**强制转换为 decimal**  

| 参数类型 | 结果 | 
| --- | --- | 
| 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”。 | 
| 数组 | 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”。 AWS IoT 尝试将字符串转换为 Decimal，然后向下舍入到最近的 Int。 | 
| 数组 | Undefined. | 
| 对象 | Undefined. | 
| Null | Undefined. | 
| 未定义 | Undefined. | 


**强制转换为 `Boolean`**  

| 参数类型 | 结果 | 
| --- | --- | 
| Int | 0 = False，任何非零值 = True。 | 
| Decimal | 0 = False，任何非零值 = True。 | 
| Boolean | 源值。 | 
| String | “true” = True 和“false” = False（不区分大小写）。其它字符串值 = Undefined。 | 
| 数组 | Undefined. | 
| 对象 | Undefined. | 
| Null | Undefined. | 
| 未定义 | Undefined. | 


**强制转换为 string**  

| 参数类型 | 结果 | 
| --- | --- | 
| 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。 | 
| 数组 | 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。 | 
| 数组 | 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。 | 
| 数组 | Undefined. | 
| 对象 | Undefined. | 
| Null | Undefined. | 
| 未定义 | Undefined. | 

## 解码（值，decodingScheme）
<a name="iot-sql-decode-base64"></a>

使用 `decode` 函数来解码一个编码的值。如果解码字符串为 JSON 文档，则返回可寻址对象。否则，解码字符串会返回为字符串。如果字符串无法解码，则函数返回 NULL。此函数支持解码 base64 编码的字符串和协议缓冲区（protobuf）消息格式。

SQL 版本 2016-03-23 及更高版本支持。

值  
字符串值或任何有效的表达式，如 [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 规则调用您的 Decode 函数。要保护您的函数，请参阅*《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`

  `FileDescriptorSet` 文件存储在名为 `s3-bucket` 的 Amazon S3 存储桶中。
+ `myproto`

  用于生成名为 `myproto.proto` 的 `FileDescriptorSet` 文件的原始 `.proto` 文件。
+ `messagetype`

  `myproto.proto` 中定义的名为 `messagetype` 的消息类型（以及任何导入的依赖项）。

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

根据编码方案，使用 `encode` 函数将有效载荷（可能是非 JSON 数据）编码为字符串表示形式。SQL 版本 2016-03-23 及更高版本支持。

值  
[AWS IoT SQL 参考](iot-sql-reference.md) 中所定义的任何有效的表达式。您可以指定 \$1 以对整个有效载荷进行编码，无论它是否为 JSON 格式。如果您提供了表达式，评估的结果将在编码之前转换为字符串。

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

## 入
<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 的范围（负值或大于等于数组长度），则结果为 Undefined。 | 
| 字符串 | 任何类型 (转换为 Int) | 在第二个参数（已经转换为 Int）提供的字符串中，从零开始索引得到的字符。如果转换已不成功，结果为 Undefined。如果索引超出字符串的范围（负值或大于等于字符串长度），则结果为 Undefined。 | 
| 对象 | String（不进行转换） | 第一个参数对象中存储的值与作为第二个参数提供的字符串键相对应。 | 
| 其它值 | 任意值 | Undefined. | 

## get\$1dynamodb（tableName、、、、、roLearn partitionKeyName） partitionKeyValue sortKeyName sortKeyValue
<a name="iot-sql-function-get-dynamodb"></a>

从 DynamoDB 表中检索数据。`get_dynamodb()` 可让您在计算规则时查询 DynamoDB 表。您可以使用从 DynamoDB 中检索到的数据筛选或增加消息有效载荷。SQL 版本 2016-03-23 及更高版本支持。

`get_dynamodb()` 接受以下参数：

tableName  
要查询的 DynamoDB 表的名称。

partitionKeyName  
分区键的名称。有关更多信息，请参阅 [DynamoDB Keys](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)。

partitionKeyValue  
用于标识记录的分区键的值。有关更多信息，请参阅 [DynamoDB Keys](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)。

sortKeyName  
（可选）排序键的名称。仅当查询的 DynamoDB 表使用复合键时需要此参数。有关更多信息，请参阅 [DynamoDB Keys](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)。

sortKeyValue  
（可选）排序键的值。仅当查询的 DynamoDB 表使用复合键时需要此参数。有关更多信息，请参阅 [DynamoDB Keys](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(name)
<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 编码的字符串，用于描述发布消息的内容。

payLoadFormat指示器  
字符串：一个枚举字符串值，指示有效载荷是否格式化为 UTF-8。有效值为 `UNSPECIFIED_BYTES` 和 `UTF8_DATA`。

responseTopic  
字符串：一个 UTF-8 编码的字符串，用作响应消息的主题名称。响应主题用于描述接收方应作为请求/响应流程的一部分发布到的主题。主题不得包含通配符。

correlationData  
字符串：请求消息的发送方使用 base64 编码的二进制数据来识别收到响应消息时响应消息的请求。

下表显示了可接受的函数参数，及其与 `get_mqtt_property` 函数相关的返回类型：


**函数参数**  

| SQL | 返回的数据类型（如果存在） | 返回的数据类型（如果不存在） | 
| --- | --- | --- | 
| get\$1mqtt\$1property("format\$1indicator") | 字符串（未指定 \$1BYTES 或 \$1DATA） UTF8 | 字符串（UNSPECIFIED\$1BYTES） | 
| get\$1mqtt\$1property("content\$1type") | 字符串 | 未定义 | 
| get\$1mqtt\$1property("response\$1topic") | 字符串 | 未定义 | 
| get\$1mqtt\$1property("correlation\$1data") | base64 编码的字符串 | 未定义 | 
| get\$1mqtt\$1property("some\$1invalid\$1name") | 未定义 | 未定义 | 

以下示例 Rules 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（表达式，默认值）
<a name="iot-sql-function-get-or-default"></a>

如果已指定，则返回第二个参数中的默认值，否则在第一个参数中的表达式返回 null、undefined 或失败时返回 undefined。SQL 版本 2016-03-23 及更高版本支持。

**重要**  
`get_or_default`不直接支持非 JSON 有效负载。如果您使用的是非 JSON 负载，请使用`encode`或`decode`函数。

`get_or_default()` 接受以下参数：

expression  
任何包含[数据类型](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 扩展](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 扩展](iot-sql-json.md)。这是第一个参数返回 null、undefined 或失败时要返回的值。  
默认值参数不允许使用从客户拥有的资源（例如 get\$1secret、get\$1dynamodb、aws\$1lambda、get\$1thing\$1shadow、decode-protobuf 和 machineLearning\$1predict）中获取数据的函数。

下表显示了每个参数的可接受函数参数及其相关输出：


| 第一个论点 | 第二个论点 | Output | 
| --- | --- | --- | 
| 成功评估 | 任何值或未指定 | 第一个参数值。 | 
| 未定义、空或失败 | 任何值，包括 “未定义” 或 “空” | 第二个参数值。 | 
| 未定义、空或失败 | 未指定 | Undefined | 

**示例：**

示例 1：

以下示例提供了 DynamoDB 表或查询失败时的默认值：

```
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()` 接受以下参数：

注册表 API  
正在调用的注册表 API。有效值为 `DescribeThing` 和 `ListThingGroupsForThing`。这些值必须是常量字符串。

thingName  
字符串：要检索其注册表数据的事物的名称。

roleArn  
字符串：根据所调用的 API 具有`iot:DescribeThing` and/or `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>

在 [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/) 中检索密钥当前版本的加密 `SecretString` 或者 `SecretBinary` 字段中的值。有关创建和维护密钥的更多信息，请参阅[CreateSecret[UpdateSecret](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_UpdateSecret.html)](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_CreateSecret.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 Secrets Manager 控制台创建为 JSON 对象的密钥： AWS CLI
  + 如果为 `key` 参数指定值，则函数返回指定键的值。
  + 如果您没有为 `key` 参数指定值，则函数将返回整个 JSON 对象。
+ 对于您使用 APIs 或作为非 JSON 对象创建的机密： AWS CLI
  + 如果为 `key` 参数指定值，则函数失败并出现异常。
  + 如果您没有为 `key` 参数指定值，则函数返回密钥的内容。  
SecretBinary  
+ 如果为 `key` 参数指定值，则函数失败并出现异常。
+ 如果您没有为 `key` 参数指定值，则函数将密钥值作为 base64 编码 UTF-8 字符串返回。

键  
（可选）字符串：存储在密钥的 `SecretString` 字段中的 JSON 对象里的键名称。如果您希望仅检索存储在密钥中而不是整个 JSON 对象中的键值，请使用此值。  
如果您为此参数指定了一个值，而密钥的 `SecretString` 字段中不包含 JSON 对象，此函数将失败并出现异常。

roleArn  
String：具有 `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  
String：您要检索其影子的事物的名称。

shadowName  
（可选）字符串：影子的名称。只有在引用命名的影子时，才需要使用该参数。

roleArn  
String：具有 `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 key') | 字符串数组 | ['some value', 'value with duplicate key'] | 
| get\$1user\$1properties('other key') | 字符串数组 | ['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('non-existent key') | 未定义 |  | 

以下示例 Rules 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>

返回第二个参数的第一个索引（从零开始）作为第一个参数的子字符串。两个参数均为字符串。如果参数数据类型不是字符串，则应用标准字符串转换规则进行转换。此函数只对字符串有效，不适用于数组。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。 | 
| 数组 | 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。 | 
| 数组 | 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，然后对该 String 应用 LPAD 函数。如果它无法转换，则结果为 Undefined。 | 
| 任意值 | 其它值 | Undefined. | 

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

从提供的 `String` 中删除所有前导空白（制表符和空格）。SQL 版本 2015-10-08 及更高版本支持。

示例：

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


****  

| 参数类型 | 结果 | 
| --- | --- | 
| Int | 删除了所有前导空白的 Int 的 String 表示形式。 | 
| Decimal | 删除了所有前导空白的 Decimal 的 String 表示形式。 | 
| Boolean | 布尔值（“true”或“false”）在删除所有前导空格之后的 String 表示形式。 | 
| String | 删除所有前导空白之后的参数。 | 
| 数组 | Array（使用标准转换规则）在删除所有前导空白之后的 String 表示形式。 | 
| 对象 | 对象（使用标准转换规则）在删除所有前导空白之后的 String 表示形式。 | 
| Null | Undefined. | 
| 未定义 | Undefined. | 

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

使用该`machinelearning_predict`函数使用基于 Amazon A SageMaker I 模型的 MQTT 消息中的数据进行预测。SQL 版本 2015-10-08 及更高版本支持。`machinelearning_predict` 函数的参数如下：

modelId  
对其运行预测的模型的 ID。必须启用模型的实时端点。

roleArn  
IAM 角色，拥有具备 `machinelearning:Predict` 和 `machinelearning:GetMLModel` 权限的策略并允许访问运行预测所针对的模型。

记录  
要传递到 SageMaker AI 预测 API 的数据。该参数应表示为单层 JSON 对象。如果记录是多级 JSON 对象，该记录将通过序列化其值来进行平展。例如，以下 JSON：  

```
{ "key1": {"innerKey1": "value1"}, "key2": 0}
```
 会变为：  

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

该函数返回具有以下字段的 JSON 对象：

predictedLabel  
基于模型的输入分类。

details  
包含以下属性：    
PredictiveModelType  
模型类型。有效值为 REGRESSION、BINARY、MULTICLASS。  
算法  
 SageMaker 人工智能用来进行预测的算法。该值必须为 SGD。

predictedScores  
包含与每个标签对应的原始分类分数。

predictedValue  
 SageMaker 人工智能预测的价值。

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

返回第一个参数除以第二个参数的余数。等效于 [remainder(Decimal, Decimal)](#iot-func-remainder)。您还可以使用“%”作为相同取模功能的插入运算符。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`函数将时间戳格式化为人类可读 date/time 的格式。SQL 版本 2016-03-23 及更高版本支持。要将时间戳字符串转换为毫秒，请参阅 [time\$1to\$1epoch(String, String)](#iot-sql-function-time-to-epoch)。

`parse_time` 函数采用下列参数：

模式  
（字符串）遵循 [Joda-](http://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html) Time 格式的 date/time 模式。

timestamp  
(Long) 要采用自 Unix 纪元时间以来的毫秒数格式表示的时间。请参阅函数 [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 设备软件开发工具包 | MQTT | X.509 设备证书 | X.509 证书指纹 | 
| AWS IoT 设备软件开发工具包 | MQTT 结束了 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 | String 的 Int 表示形式。 | 
| Decimal | String 的 Decimal 表示形式。 | 
| Boolean | 布尔值（“true”或“false”）的 String 表示形式。 | 
| String | String。 | 
| 数组 | Array (使用标准转换规则) 的 String 表示形式。 | 
| 对象 | 对象 (使用标准转换规则) 的 String 表示形式。 | 
| Null | Undefined. | 
| 未定义 | Undefined. | 

*第二个参数：*

必须是有效的正则表达式。非字符串类型使用标准转换规则转换为 `String`。根据类型，生成的字符串可能不是有效的正则表达式。如果（转换后的）参数不是有效的正则表达式，则结果为 `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 | String 的 Int 表示形式。 | 
| Decimal | String 的 Decimal 表示形式。 | 
| Boolean | 布尔值（“true”或“false”）的 String 表示形式。 | 
| String | 源值。 | 
| 数组 | Array (使用标准转换规则) 的 String 表示形式。 | 
| 对象 | 对象 (使用标准转换规则) 的 String 表示形式。 | 
| Null | Undefined. | 
| 未定义 | Undefined. | 

*第二个参数：*

必须是有效的正则表达式。非字符串类型使用标准转换规则转换为 `String`。根据类型，生成的字符串可能不是有效的正则表达式。如果（转换后的）参数不是有效的正则表达式，则结果为 `Undefined`。

*第三个参数：*

必须是有效的正则表达式替代字符串。（可以引用捕获组。） 非字符串类型使用标准转换规则转换为 `String`。如果（转换后的）参数不是有效的正则表达式替代字符串，则结果为 `Undefined`。

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

在第一个参数中查找第二个参数（正则表达式）的第一个匹配项。用“\$1”引用捕获组。SQL 版本 2015-10-08 及更高版本支持。

示例：

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

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


**第一个参数：**  

| 参数类型 | 结果 | 
| --- | --- | 
| Int | String 的 Int 表示形式。 | 
| Decimal | String 的 Decimal 表示形式。 | 
| Boolean | 布尔值（“true”或“false”）的 String 表示形式。 | 
| String | String 参数。 | 
| 数组 | Array (使用标准转换规则) 的 String 表示形式。 | 
| 对象 | 对象 (使用标准转换规则) 的 String 表示形式。 | 
| Null | Undefined. | 
| 未定义 | Undefined. | 

*第二个参数：*

必须是有效的正则表达式。非字符串类型使用标准转换规则转换为 `String`。根据类型，生成的字符串可能不是有效的正则表达式。如果（转换后的）参数不是有效的正则表达式，则结果为 `Undefined`。

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

返回第一个参数除以第二个参数的余数。等效于 [mod(Decimal, Decimal)](#iot-func-mod)。您还可以使用“%”作为相同取模功能的插入运算符。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 | String 的 Int 表示形式。 | 
| Decimal | String 的 Decimal 表示形式。 | 
| Boolean | 布尔值（“true”或“false”）的 String 表示形式。 | 
| String | 源值。 | 
| 数组 | Array (使用标准转换规则) 的 String 表示形式。 | 
| 对象 | 对象 (使用标准转换规则) 的 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，然后对该 String 应用 rpad 函数。如果它无法转换，则结果为 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` 中删除所有尾随空白（制表符和空格）。SQL 版本 2015-10-08 及更高版本支持。

示例：

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


****  

| 参数类型 | 结果 | 
| --- | --- | 
| Int | String 的 Int 表示形式。 | 
| Decimal | String 的 Decimal 表示形式。 | 
| Boolean | 布尔值（“true”或“false”）的 String 表示形式。 | 
| 数组 | Array (使用标准转换规则) 的 String 表示形式。 | 
| 对象 | 对象 (使用标准转换规则) 的 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。 | 
| 数组 | 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。 | 
| 数组 | 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 地址。您也可以检索 IPv6 消息 IPv4 和消息的源 IP。源 IP 将如下所示：

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

IPv4: `xxx.xxx.xxx.xxx`

**注意**  
不会通过[重新发布操作](republish-rule-action.md)传递原始源 IP。

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

输入值为 `String` 后跟一个或两个 `Int` 值。对于 `String` 和单个 `Int` 参数，此函数在输入的 `String` 中从指定的 `Int` 索引（从零开始，包括零）到 `String` 结束提取子字符串并返回。对于 `String` 和两个 `Int` 参数，此函数在输入的 `String` 中从第一个 `Int` 索引参数（从零开始，包括零）到第二个 `Int` 索引参数（从零开始，包括零）提取子字符串并返回。索引小于零时将设置为零。大于 `String` 长度的索引设置为 `String` 长度。在三个参数的版本中，如果第一个索引大于等于第二个索引，那么结果为空 `String`。

 如果提供的参数不是 (*String*、*Int*) 或 (*String*、*Int*、*Int*)，则将对参数应用标准转换以尝试将其转换为正确的类型。如果无法转换类型，函数的结果为 `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。 | 
| 数组 | 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。 | 
| 数组 | 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。 | 
| 数组 | Undefined. | 
| 对象 | Undefined. | 
| Null | Undefined. | 
| 未定义 | Undefined. | 

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

使用 `time_to_epoch` 函数将时间戳字符串转换为 Unix 纪元时间的毫秒数。SQL 版本 2016-03-23 及更高版本支持。要将毫秒转换为格式化的时间戳字符串，请参阅 [parse\$1time(String, Long[, String])](#iot-sql-function-parse-time)。

`time_to_epoch` 函数采用下列参数：

timestamp  
（字符串）要转换为自 Unix 纪元以来毫秒数的时间戳字符串。如果时间戳字符串未指定时区，则函数将使用 UTC 时区。

模式  
（字符串）遵循[JDK11 时间格式](http://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html)的 date/time 模式。

示例：

`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 日星期四协调世界时 (UTC) 00:00:00 开始的当前时间戳（以毫秒为单位）。 AWS IoT SQL 版本 2015-10-08 及更高版本支持。

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

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

返回已向其发送触发规则的消息的主题。如果未指定参数，则返回整个主题。`Decimal` 参数用于指定特定主题段，使用 1 指定第一个段。对于主题 `foo/bar/baz`，主题（1）将返回 `foo`，主题（2）将返回 `bar`，以此类推。SQL 版本 2015-10-08 及更高版本支持。

示例：

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

`topic(1)` = “things”

在使用[基本提取](iot-basic-ingest.md)功能时，主题的初始前缀 (`$aws/rules/rule-name`) 对 topic() 函数不可用。例如，给定以下主题：

`$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>

返回对象数组，其中包含 `Object` 参数对 `Array` 参数的指定转换结果。

SQL 版本 2016-03-23 及更高版本支持。

字符串  
要使用的转换模式。有关支持的转换模式以及这些模式如何利用 `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 语句使用 `String` 值为 `enrichArray` 的 **transform()** 函数。在本例中，`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 语句使用 `String` 值为 `enrichArray` 的 **transform()** 函数。**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。 | 
| 数组 | String（使用标准转换规则）的 Array 表示形式。 | 
| 对象 | 对象（使用标准转换规则）的 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 子句中指定文本对象，该对象可用于传递信息。

**注意**  
文本只能在使用 SQL 版本 2016-03-23 或更高版本时使用。

使用 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]}`。

# Case 语句
<a name="iot-sql-case"></a>

Case 语句可以用于执行分支，就像 switch 语句一样。

语法：

```
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`，则 Case 语句的结果为 `Undefined`。

# JSON 扩展
<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>

您可以使用替换模板来增加触发规则并 AWS IoT 执行操作时返回的 JSON 数据。替换模板的语法是`${`*表达式`}`，其中*表达*式*可以是 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 日志](cloudwatch-logs-rule-action.md)
+ [CloudWatch 指标](cloudwatch-metrics-rule-action.md)
+ [DynamoDB](dynamodb-rule-action.md)
+ [迪纳摩 DBv2](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-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)
+ [Step Functions](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` 子句的示例。
+ 对于二进制有效载荷，您可以将以下 `SELECT` 子句仅与 \$1 一起使用。
  + 

    ```
    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 规则通过提供[解码（值，decodingScheme）](iot-sql-functions.md#iot-sql-decode-base64)SQL 函数来支持 protobuf，该函数允许您将由 protobuf 编码的消息负载解码为 JSON 格式并将其路由到下游服务。本节详细介绍了在 “规则” 中配置 protobuf 解码的 step-by-step过程。 AWS IoT Core 

**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>

创建描述符文件后，使用 AWS API `<FILENAME>.desc`、S AWS DK 或，`<FILENAME>.desc`将描述符文件上传到 Amazon S3 存储桶。 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 存储桶中备份您的原型文件。

  备份您的原型文件是一种很好的做法，以防出现问题。例如，如果您在运行 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 日志记录，这样你就可以在中查看账户的 AWS IoT 日志 CloudWatch。当规则的 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`。您对 `FileDescriptorSet` 的更新最多需要 15 分钟能够反映出来。为了避免这一延迟，使用新的对象键上传更新后的 `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-03-23 SQL 规则引擎版本中的新增功能
<a name="sql-2016-03-23-beta"></a>
+ 针对选择嵌套 JSON 对象的修复程序。
+ 针对阵列查询的修复程序。
+ 对象内查询支持。有关更多信息，请参阅 [嵌套对象查询](iot-sql-nested-queries.md)。
+ 支持将阵列作为顶级对象输出。
+ 添加可应用于 JSON 和非 JSON 格式数据的 `encode(value, encodingScheme)` 函数。有关更多信息，请参阅[编码函数](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]
```