

# 更新 Iceberg 表数据
<a name="querying-iceberg-updating-iceberg-table-data"></a>

您可以通过使用 `INSERT`、`UPDATE` 和 `DELETE` 查询直接在 Athena 上管理 Iceberg 表数据。每个数据管理事务都会生成一个新的快照，可以使用时间旅行查询该快照。`UPDATE` 和 `DELETE` 语句遵循 Iceberg 格式 v2 行级[位置删除](https://iceberg.apache.org/spec/#position-delete-files)规范并强制执行快照隔离。

**注意**  
Athena SQL 目前不支持“写入时复制”方法。无论指定的表属性如何，`UPDATE`、`MERGE INTO` 和 `DELETE FROM` 操作始终会使用具有位置删除功能的“读取时合并”方法。如果您设置了诸如 `write.update.mode`、`write.merge.mode` 和/或 `write.delete.mode` 等使用“写入时复制”的表属性，您的查询不会失败，因为 Athena 会忽略它们并继续使用“读取时合并”方法。

使用以下命令对 Iceberg 表执行数据管理操作。

**Topics**
+ [INSERT INTO](querying-iceberg-insert-into.md)
+ [DELETE](querying-iceberg-delete.md)
+ [UPDATE](querying-iceberg-update.md)
+ [MERGE INTO](querying-iceberg-merge-into.md)

# INSERT INTO
<a name="querying-iceberg-insert-into"></a>

将数据插入 Iceberg 表。Athena Iceberg `INSERT INTO` 收费与当前对外部 Hive 表进行 `INSERT INTO` 查询的收费一致，皆按扫描的数据量收费。要将数据插入到 Iceberg 表中，请使用以下语法，其中 *query* 可以是 `VALUES (val1, val2, ...)` 或 `SELECT (col1, col2, …) FROM [db_name.]table_name WHERE predicate`。有关 SQL 语法和语义的详细信息，请参阅 [INSERT INTO](insert-into.md)。

```
INSERT INTO [db_name.]table_name [(col1, col2, …)] query
```

以下示例将值插入到表 `iceberg_table` 中。

```
INSERT INTO iceberg_table VALUES (1,'a','c1')
```

```
INSERT INTO iceberg_table (col1, col2, ...) VALUES (val1, val2, ...)
```

```
INSERT INTO iceberg_table SELECT * FROM another_table
```

# DELETE
<a name="querying-iceberg-delete"></a>

Athena Iceberg `DELETE` 将 Iceberg 位置删除文件写入表中。这称为读取时合并删除。与写入时复制删除不同，读取时合并删除效率更高，因为其不会重写文件数据。当 Athena 读取 Iceberg 数据时，将合并 Iceberg 位置删除文件与数据文件，以生成表的最新视图。若要删除这些位置删除文件，您可以运行 [REWRITE DATA 压缩操作](querying-iceberg-data-optimization.md#querying-iceberg-data-optimization-rewrite-data-action)。`DELETE` 操作按扫描的数据量收费。有关语法，请参阅 [删除](delete-statement.md)。

以下示例从 `iceberg_table` 中删除 `c3` 作为 `category` 的值的行。

```
DELETE FROM iceberg_table WHERE category='c3'
```

# UPDATE
<a name="querying-iceberg-update"></a>

Athena Iceberg `UPDATE` 将 Iceberg 位置删除文件和新更新的行作为数据文件写入同一事务中。`UPDATE` 可视为 `INSERT INTO` 和 `DELETE` 的组合。`UPDATE` 操作按扫描的数据量收费。有关语法，请参阅 [UPDATE](update-statement.md)。

以下示例更新表 `iceberg_table` 中的指定值。

```
UPDATE iceberg_table SET category='c2' WHERE category='c1'
```

# MERGE INTO
<a name="querying-iceberg-merge-into"></a>

有条件地更新行、删除行或将行插入到 Iceberg 表中。单个语句可以组合更新、删除和插入操作。有关语法，请参阅 [MERGE INTO](merge-into-statement.md)。

**注意**  
`MERGE INTO` 是事务性的，仅支持用于 Athena 引擎版本 3 中的 Apache Iceberg 表。

以下示例从表 `t` 中删除源表 `s` 中的所有客户。

```
MERGE INTO accounts t USING monthly_accounts_update s
ON t.customer = s.customer
WHEN MATCHED
THEN DELETE
```

以下示例使用源表 `s` 中的客户信息更新目标表 `t`。如果表 `t` 与表 `s` 中的客户行匹配，则该示例会增加表 t 中的购买量。如果表 `t` 与表 `s` 中的客户行不匹配，则该示例会将表 `s` 的客户行插入到表 `t` 中。

```
MERGE INTO accounts t USING monthly_accounts_update s
    ON (t.customer = s.customer)
    WHEN MATCHED
        THEN UPDATE SET purchases = s.purchases + t.purchases
    WHEN NOT MATCHED
        THEN INSERT (customer, purchases, address)
              VALUES(s.customer, s.purchases, s.address)
```

以下示例使用源表 `s` 中的信息有条件地更新目标表 `t`。该示例删除了源地址为 Centreville 的所有匹配的目标行。对于所有其他匹配的行，该示例会添加源采购并将目标地址设置为源地址。如果目标表中没有匹配项，该示例会插入源表中的行。

```
MERGE INTO accounts t USING monthly_accounts_update s
    ON (t.customer = s.customer)
    WHEN MATCHED AND s.address = 'Centreville'
        THEN DELETE
    WHEN MATCHED
        THEN UPDATE
            SET purchases = s.purchases + t.purchases, address = s.address
    WHEN NOT MATCHED
        THEN INSERT (customer, purchases, address)
              VALUES(s.customer, s.purchases, s.address)
```