INSERT(多表)¶
通过在表中插入一个或多个具有列值的行(来自查询)来更新多个表。支持无条件插入和有条件插入。
- 另请参阅:
语法¶
-- Unconditional multi-table insert
INSERT [ OVERWRITE ] ALL
intoClause [ ... ]
<subquery>
-- Conditional multi-table insert
INSERT [ OVERWRITE ] { FIRST | ALL }
{ WHEN <condition> THEN intoClause [ ... ] }
[ ... ]
[ ELSE intoClause ]
<subquery>
其中:
intoClause ::= INTO <target_table> [ ( <target_col_name> [ , ... ] ) ] [ VALUES ( { <source_col_name> | DEFAULT | NULL } [ , ... ] ) ]
必填参数¶
ALL
仅限无条件多表插入
指定每一行执行 INSERT 语句中的每个
INTO
子句。备注
如果在无条件多表插入中指定了
FIRST
关键字(或者未指定ALL
关键字),则 Snowflake 返回语法错误。FIRST
或ALL
仅限条件多表插入
FIRST
指定每行仅执行条件计算结果为 TRUE 的第一个
WHEN
子句。如果没有WHEN
子句的计算结果为 TRUE,则执行ELSE
子句(如果存在)。ALL
指定每行执行所有
WHEN
子句。如果没有WHEN
子句的计算结果为 TRUE,则执行ELSE
子句(如果存在)。
备注
条件多表插入必须至少包含一个
WHEN
子句。每个
WHEN
子句可以包含多个INTO
子句,并且这些INTO
子句可以插入同一个目标表。要始终执行
WHEN
子句,请使用:WHEN 1=1 THEN ...
condition
仅限条件多表插入
指定计算结果必须为 TRUE 的条件,以便插入
INTO
子句中指定的值。条件可以是 SELECT 列表。target_table
指定要在其中插入行的目标表。同一表可以(在单独的
WHEN
子句中)多次引用。通过为每个表包含一个
INTO
子句,可以定位多个表。subquery
指定 SELECT 列表,用于确定要插入目标表的值的来源。
可选参数¶
OVERWRITE
指定在插入表之前截断目标表,同时保留对表的访问控制权限。
带
OVERWRITE
的 INSERT 语句可以在当前事务的作用域内进行处理,从而避免提交事务的 DDL 语句,例如:DROP TABLE t; CREATE TABLE t AS SELECT * FROM ... ;
默认值:无值(在执行插入之前 ` 不会 :emph:` 截断目标表)
( target_col_name [ , ... ] )
指定目标表中的一列或多列,在其中插入源中相应列的值。指定的目标列数必须与源中指定的值数匹配。
默认值:无值(目标表中的 :emph:` 所有 ` 列都会更新)
VALUES ( source_col_name | DEFAULT | NULL [ , ... ] )
指定要插入到目标表的相应列中的一个或多个值。这些值可以是:
source_col_name
:指定源中的列,包含要插入目标表中相应列的值。DEFAULT
:插入目标表中相应列的默认值。NULL
:插入NULL
值。
该子句中的每个值都必须用逗号分隔。此外,指定的值数必须与为目标表指定的列数匹配。
默认值:无值(源中 ` 所有 :emph:` 列的值都插入目标表中的相应列)
使用说明¶
在
INTO
子句中,VALUES
子句可选。如果省略,则 SELECT 列表中的值按其自然顺序插入目标表。WHEN
子句中的表达式(用于条件多表插入)和VALUES
子句只能通过别名引用子查询。别名必须是以下其中一项:为 SELECT 表达式指定的显式别名。
表达式的默认别名。
位置别名($1、$2 等)。
此外,最外层 SELECT 列表中不包含的子查询的列和表达式不能在
WHEN
和VALUES
子句中引用。有关详细信息,请参阅 ` 示例 `_ (本主题内容)。在
subquery
生成的每一行中,source_col_name
中的值必须与相应target_col_name
的数据类型兼容。此规则甚至适用于按WHEN
子句中condition
筛选出的行。操作顺序不能保证,在针对数据类型兼容性计算source_col_name
中的值之前,会应用WHEN
子句中的筛选器。
示例¶
无条件多表插入¶
将 src
表中的每一行插入表 t1
和 t2
中 :emph:` 两次 `。在此示例中,插入的行不完全相同;插入的每一行都有不同的值/顺序,因为我们使用 VALUES 子句来改变数据:
INSERT ALL INTO t1 INTO t1 (c1, c2, c3) VALUES (n2, n1, DEFAULT) INTO t2 (c1, c2, c3) INTO t2 VALUES (n3, n2, n1) SELECT n1, n2, n3 from src; -- If t1 and t2 need to be truncated before inserting, OVERWRITE must be specified INSERT OVERWRITE ALL INTO t1 INTO t1 (c1, c2, c3) VALUES (n2, n1, DEFAULT) INTO t2 (c1, c2, c3) INTO t2 VALUES (n3, n2, n1) SELECT n1, n2, n3 from src;
条件多表插入¶
接下来的两个示例演示如何使用 WHEN
子句和 ELSE
子句,确定每行插入哪个表(如果有),从而创建条件多表插入。
这些示例还演示 INSERT ALL
与 INSERT FIRST
之间的使用区别。
执行带 ELSE
子句的所有 WHEN
子句:
同时满足
n1 > 100
和n1 > 10
的行,因此在使用ALL
关键字时会在t1
中插入两次。n1 <= 10
满足ELSE
情况的行,因此插入t2
。INSERT ALL WHEN n1 > 100 THEN INTO t1 WHEN n1 > 10 THEN INTO t1 INTO t2 ELSE INTO t2 SELECT n1 from src;
如果表 src 包含 3 行,其中 n1 的值为 1、11 和 101,则在 INSERT 语句之后,表 t1 和 t2 将包含如下所示的值:
t1:
101 |
101 > 100,因此第一个 |
101 |
101 > 10,因此第二个 |
11 |
11 > 10,因此第二个 |
带 n1 = 1
的行未插入 t1 中,因为它不满足插入 t1 中的任何 WHEN
子句,并且 ELSE
子句未插入 t1 中。
t2:
101 |
101 > 10,因此第二个 |
11 |
11 > 10,因此第二个 |
1 |
该行不满足任何 |
下一个示例与上一个示例类似,只是带有一个 FIRST
子句。
INSERT FIRST WHEN n1 > 100 THEN INTO t1 WHEN n1 > 10 THEN INTO t1 INTO t2 ELSE INTO t2 SELECT n1 from src;
如果表 src 包含 3 行,其中 n1 的值为 1、11 和 101,则在 INSERT 语句之后,表 t1 和 t2 将包含如下所示的值:
t1:
101 |
101 > 100,因此第一个 |
11 |
11 > 10,因此第二个 |
带 n1 = 1
的行未插入 t1 中,因为它不满足插入 t1 中的任何 WHEN
子句,并且 ELSE
子句未插入 t1 中。
与前面使用 ALL
的示例不同,带 n1 = 101
的行仅插入 t1 中一次,因为 第一个 WHEN
子句的计算结果为 TRUE,因此第二个 WHEN
子句被忽略。
t2:
11 |
11 > 10,因此第二个 |
1 |
该行不满足任何 |
该行 n1 = 101
未插入 t2 中,因为 101 大于 100,因此它与第一个 WHEN
子句匹配,但第一个 WHEN
子句未插入 t2 中,并且该语句不会检查任何其他 WHEN
子句或使用该 ELSE
子句,因为该行已经符合第一个 WHEN
子句的条件。
带别名和引用的多表插入¶
使用位置别名 ($1
)、显式别名 (an_alias
) 和默认别名 ("10 + 20"
) 插入值;此示例将带值 (1, 50, 30)
的单个行插入表 t1
:
INSERT ALL INTO t1 VALUES ($1, an_alias, "10 + 20") SELECT 1, 50 AS an_alias, 10 + 20;
说明如何从必须选择引用的列中插入值(表 src
中的 b
和 c
):
-- Returns error INSERT ALL WHEN c > 10 THEN INTO t1 (col1, col2) VALUES (a, b) SELECT a FROM src; -- Completes successfully INSERT ALL WHEN c > 10 THEN INTO t1 (col1, col2) VALUES (a, b) SELECT a, b, c FROM src;
说明如何从无法引用的列中插入值 (src1.key
);相反,必须选择该列并使用别名:
-- Returns error INSERT ALL INTO t1 VALUES (src1.key, a) SELECT src1.a AS a FROM src1, src2 WHERE src1.key = src2.key; -- Completes successfully INSERT ALL INTO t1 VALUES (key, a) SELECT src1.key AS key, src1.a AS a FROM src1, src2 WHERE src1.key = src2.key;