INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
{ SELECT ...
| TABLE table_name
| VALUES row_constructor_list
}
[ON DUPLICATE KEY UPDATE assignment_list]
value:
{expr | DEFAULT}
value_list:
value [, value] ...
row_constructor_list:
ROW(value_list)[, ROW(value_list)][, ...]
assignment:
col_name =
value
| [row_alias.]col_name
| [tbl_name.]col_name
| [row_alias.]col_alias
assignment_list:
assignment [, assignment] ...
使用 插入 ... 选择
,您可以快速将许多行插入到表中,从 选择
语句的结果中,该语句可以从一个或多个表中选择。例如:
INSERT INTO tbl_temp2 (fld_id)
SELECT tbl_temp1.fld_order_id
FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
INSERT INTO ta TABLE tb;
表 tb
等同于 选择 * FROM tb
。它在插入源表的所有列到目标表时非常有用,并且不需要使用 WHERE 进行过滤。此外,来自 表
的行可以使用 ORDER BY
按一个或多个列排序,并且可以使用 LIMIT
子句限制插入的行数。有关更多信息,请参阅 第 15.2.16 节,“表语句”。
以下条件适用于 插入 ... 选择
语句,并且(除非另有说明)也适用于 插入 ... 表
语句:
-
指定
忽略
以忽略可能导致重复键违规的行。 -
目标表可能出现在
插入
语句的FROM
子句中,或者作为表
语句命名的表。然而,您不能在同一个语句中插入到表中并从同一个表中选择。当从同一个表中选择和插入时,MySQL 创建一个内部临时表来保存
选择
的结果,然后将这些行插入到目标表中。然而,您不能使用插入 INTO t ... 选择 ... FROM t
当t
是一个临时表时,因为临时表不能在同一个语句中被引用两次。出于同样的原因,您不能使用插入 INTO t ... 表 t
当t
是临时表时。请参阅 第 10.4.4 节,“MySQL 中的内部临时表使用” 和 B.3.6.2 节,“临时表问题”。 -
AUTO_INCREMENT
列按通常方式工作。 -
为了确保二进制日志可以用来重新创建原始表,MySQL 不允许
插入 ... 选择
或插入 ... 表
语句的并发插入(请参阅 第 10.11.3 节,“并发插入”)。 -
为了避免ambiguous 列引用问题,当
选择
和插入
都引用同一个表时,请为选择
部分中的每个表提供唯一的别名,并使用该别名限定该部分中的列名。表
语句不支持别名。
您可以使用 PARTITION
子句明确选择源表或目标表(或两者)的哪些分区或子分区将被使用。当 PARTITION
用于 SELECT
语句的源表名称时,只有在其分区列表中命名的分区或子分区中的行将被选择。当 PARTITION
用于目标表的 INSERT
部分时,必须能够将所有选定的行插入到分区列表中命名的分区或子分区中。否则,INSERT ... SELECT
语句将失败。有关更多信息和示例,请参阅 第 26.5 节,“分区选择”。
TABLE
不支持 PARTITION
子句。
对于 INSERT ... SELECT
语句,请参阅 第 15.2.7.2 节,“INSERT ... ON DUPLICATE KEY UPDATE 语句”,了解在 ON DUPLICATE KEY UPDATE
子句中可以引用 SELECT
列的条件。这也适用于 INSERT ... TABLE
。
不带 ORDER BY
子句的 SELECT
或 TABLE
语句返回行的顺序是非确定性的。这意味着,在使用复制时,没有保证这种 SELECT
语句在源和副本上返回行的顺序相同,这可能会导致它们之间的不一致。为了防止这种情况,始终编写使用 ORDER BY
子句的 INSERT ... SELECT
或 INSERT ... TABLE
语句,以便在源和副本上产生相同的行顺序。另请参阅 第 19.5.1.18 节,“复制和 LIMIT”。
由于这个问题,INSERT ... SELECT ON DUPLICATE KEY UPDATE
和 INSERT IGNORE ... SELECT
语句被标记为基于语句的复制不安全。这些语句在使用基于语句的模式时将在错误日志中生成警告,并在使用混合模式时以基于行的格式写入二进制日志。(Bug #11758262,Bug #50439)