13.2.5 INSERT 语句

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    {VALUES | VALUE} (value_list) [, (value_list)] ...
    [ON DUPLICATE KEY UPDATE assignment_list]

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    SET assignment_list
    [ON DUPLICATE KEY UPDATE assignment_list]

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    SELECT ...
    [ON DUPLICATE KEY UPDATE assignment_list]

value:
    {expr | DEFAULT}

value_list:
    value [, value] ...

assignment:
    col_name = value

assignment_list:
    assignment [, assignment] ...

INSERT将新行插入到现有 table 中。语句的插入...值插入...设置形式基于明确指定的值插入行。 插入...选择table 单插入从另一个 table 或多个 table 中选择的行。如果要插入的行将导致UNIQUE索引或PRIMARY KEY中的重复值,则带有ON DUPLICATE KEY UPDATE子句的INSERT可以更新现有行。

有关插入...选择插入...在重复的密钥更新上的其他信息,请参见第 13.2.5.1 节“ INSERT ... SELECT 语句”第 13.2.5.2 节“在重复密钥更新语句上插入...”

在 MySQL 5.7 中,DELAYED关键字被接受但被服务器忽略。因此,请参见第 13.2.5.3 节“ INSERT DELAYED 语句”

插入 table 需要 table 的INSERT特权。如果使用ON DUPLICATE KEY UPDATE子句,并且使用重复键代替执行UPDATE,则该语句需要UPDATE特权才能更新列。对于已读取但未修改的列,您仅需要SELECT特权(例如,仅在ON DUPLICATE KEY UPDATE子句中* col_name * = * expr *赋值的右侧引用的列)。

当插入分区 table 时,您可以控制哪些分区和子分区接受新行。 PARTITION选项获取 table 的一个或多个分区或子分区(或两者)的逗号分隔名称列 table。如果给定的INSERT语句插入的任何行与列出的分区之一都不匹配,则INSERT语句将失败,并显示错误“找到与给定的分区集不匹配的行”。有关更多信息和示例,请参见第 22.5 节“分区选择”

您可以使用REPLACE而不是INSERT来覆盖旧行。 REPLACE在处理新行时与INSERT IGNORE相对,该新行包含与旧行重复的唯一键值:新行替换了旧行,而不是被丢弃。参见第 13.2.8 节“ REPLACE 语句”

列值可以通过几种方式给出:

如果启用了严格的 SQL 模式,则INSERT语句未为没有默认值的每个列都指定一个显式值时,将生成错误。参见第 5.1.10 节“服务器 SQL 模式”

INSERT INTO tbl_name () VALUES();

如果未启用严格模式,则 MySQL 对没有明确定义默认值的任何列使用隐式默认值。如果启用了严格模式,则任何列都没有默认值都会发生错误。

INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);

但是以下内容不合法,因为col1的值引用col2,该值是在col1之后分配的:

INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);

包含AUTO_INCREMENT值的列会发生异常。由于AUTO_INCREMENT个值是在其他值分配之后生成的,因此对分配中AUTO_INCREMENT列的任何引用都将返回0

使用VALUES语法的INSERT语句可以插入多行。为此,请包括多个用逗号分隔的列值的列 table,列 table 用括号括起来并用逗号分隔。例:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);

每个值列 table 必须包含与每行要插入的值一样多的值。以下语句无效,因为它包含一个九个值的列 table,而不是三个三个值的列 table:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3,4,5,6,7,8,9);

在这种情况下,VALUEVALUES的同义词。既不暗示关于值列 table 的数量,也不暗示每个列 table 的值的数量。无论是单个值列 table 还是多个列 table,无论每个列 table 的值数量如何,都可以使用。

可以使用ROW_COUNT() SQL 函数或mysql_affected_rows() C API 函数获得INSERT的受影响行值。参见第 12.15 节“信息功能”第 27.7.6.1 节“ mysql_affected_rows()”

如果您使用带有多个值列 table 的插入...值语句或插入...选择,则该语句以以下格式返回信息字符串:

Records: N1 Duplicates: N2 Warnings: N3

如果使用的是 C API,则可以通过调用mysql_info()函数获取信息字符串。参见第 27.7.6.36 节“ mysql_info()”

Recordstable 示该语句处理的行数。 (这不一定是实际插入的行数,因为Duplicates可以为非零.)Duplicatestable 示由于它们会复制某些现有唯一索引值而无法插入的行数。 Warningstable 示尝试插入以某种方式存在问题的列值的次数。在以下任何情况下都可能发生警告:

如果INSERT在具有AUTO_INCREMENT列的 table 中插入一行,则可以使用LAST_INSERT_ID() SQL 函数或mysql_insert_id() C API 函数找到用于该列的值。

Note

这两个功能的行为并不总是相同的。 INSERT语句相对于AUTO_INCREMENT列的行为将在第 12.15 节“信息功能”第 27.7.6.38 节“ mysql_insert_id()”中进一步讨论。

INSERT语句支持以下修饰符:

LOW_PRIORITY仅影响仅使用 table 级锁定的存储引擎(例如MyISAMMEMORYMERGE)。

Note

LOW_PRIORITY通常不应与MyISAMtable 一起使用,因为这样做会禁用并发插入。参见第 8.11.3 节“并发插入”

HIGH_PRIORITY仅影响仅使用 table 级锁定的存储引擎(例如MyISAMMEMORYMERGE)。

IGNORE对插入分区 table 的效果类似,在分区 table 中找不到与给定值匹配的分区。如果没有IGNORE,则此类INSERT语句会因错误而中止。使用INSERT IGNORE时,对于包含不匹配值的行,插入操作将以静默方式失败,但是将插入匹配的行。有关示例,请参见第 22.2.2 节“列 table 分区”

如果未指定IGNORE,则会触发错误的数据转换将中止该语句。使用IGNORE,无效值将调整为最接近的值并插入;产生警告,但该语句不会中止。您可以使用mysql_info() C API 函数确定 table 中实际插入了多少行。

有关更多信息,请参见IGNORE 关键字和严格 SQL 模式的比较

使用存储引擎(例如MyISAM)使用 table 级锁来影响分区 table 的INSERT语句仅锁定那些实际插入行的分区。 (对于使用行级锁定的诸如InnoDB之类的存储引擎,不会发生分区锁定。)有关更多信息,请参见第 22.6.4 节“分区和锁定”

首页