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 ... SELECT
,您可以快速地将 SELECT
语句(该语句可以从一个或多个表中选择)的结果插入到表中,例如
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;
TABLE tb
等同于 SELECT * FROM tb
。当将源表中的所有列插入到目标表中,并且不需要使用 WHERE 进行筛选时,这非常有用。此外,可以使用 ORDER BY
对 TABLE
中的行的顺序进行排序,并可以使用 LIMIT
子句限制插入的行数。有关更多信息,请参阅 第 15.2.16 节“TABLE 语句”.
以下条件适用于 INSERT ... SELECT
语句,并且除了特别说明外,还适用于 INSERT ... TABLE
。
指定
IGNORE
以忽略会导致重复键冲突的行。在
INSERT
语句中,目标表可能出现在SELECT
部分查询的FROM
子句中,或者作为由TABLE
命名的表。但是,您不能在子查询中将数据插入一个表并从同一个表中选择数据。当从同一个表中选择数据并插入数据时,MySQL 会创建一个内部临时表来保存来自
SELECT
的行,然后将这些行插入目标表。但是,当t
是一个TEMPORARY
表时,您不能使用INSERT INTO t ... SELECT ... FROM t
,因为TEMPORARY
表不能在同一个语句中被引用两次。出于同样的原因,当t
是一个临时表时,您不能使用INSERT INTO t ... TABLE t
。请参阅 第 10.4.4 节,“MySQL 中内部临时表的使用” 和 第 B.3.6.2 节,“TEMPORARY 表问题”。AUTO_INCREMENT
列按预期工作。为了确保可以使用二进制日志来重新创建原始表,MySQL 不允许对
INSERT ... SELECT
或INSERT ... TABLE
语句进行并发插入(请参阅 第 10.11.3 节,“并发插入”)。为了避免在
SELECT
和INSERT
引用同一个表时出现不明确的列引用问题,请为SELECT
部分中使用的每个表提供唯一的别名,并在该部分中使用相应的别名限定列名。TABLE
语句不支持别名。
您可以使用在表名后跟随的 PARTITION
子句显式选择要使用的源表或目标表(或两者)的哪些分区或子分区(或两者)。当 PARTITION
与 SELECT
部分语句中的源表名称一起使用时,仅从其分区列表中命名的分区或子分区中选择行。当 PARTITION
与 INSERT
部分语句的目标表名称一起使用时,必须能够将所有选定的行插入选项后面的分区列表中命名的分区或子分区中。否则,INSERT ... SELECT
语句将失败。有关更多信息和示例,请参阅 第 26.5 节,“分区选择”。
TABLE
不支持 PARTITION
子句。
对于 INSERT ... SELECT
语句,请参阅 第 15.2.7.2 节,“INSERT ... ON DUPLICATE KEY UPDATE 语句”,了解 SELECT
列可以在 ON DUPLICATE KEY UPDATE
子句中引用的条件。这也适用于 INSERT ... TABLE
。
不带 ORDER BY
子句的 SELECT
或 TABLE
语句返回行的顺序是不确定的。这意味着,当使用复制时,不能保证这样的 SELECT
在源和副本上按相同的顺序返回行,这可能导致它们之间出现不一致。为了防止这种情况发生,始终使用 ORDER BY
子句编写要复制的 INSERT ... SELECT
或 INSERT ... TABLE
语句,该子句在源和副本上产生相同的行顺序。另请参阅 第 19.5.1.19 节,“复制和 LIMIT”。
由于这个问题,INSERT ... SELECT ON DUPLICATE KEY UPDATE
和 INSERT IGNORE ... SELECT
语句被标记为对基于语句的复制不安全。此类语句在使用基于语句的模式时会在错误日志中生成警告,并且在使用 MIXED
模式时以基于行的格式写入二进制日志。(Bug #11758262,Bug #50439)