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
将新行插入到现有表中。语句的INSERT
... VALUES
and
INSERT ... SET
形式根据明确指定的值插入行。该INSERT
... SELECT
表单插入从另一个表或多个表中选择的行。如果要插入的行会导致索引或中出现重复值, INSERT
with
ON DUPLICATE KEY UPDATE
子句可以更新现有行。
UNIQUE
PRIMARY
KEY
有关
INSERT ...
SELECT
and
的更多信息INSERT ... ON
DUPLICATE KEY UPDATE
,请参阅
第 13.2.5.1 节,“INSERT ... SELECT 语句”和
第 13.2.5.2 节,“INSERT ... ON DUPLICATE KEY UPDATE 语句”。
插入表需要表的
INSERT
权限。如果ON DUPLICATE KEY UPDATE
使用该子句并且重复键导致UPDATE
执行 an,则该语句需要
UPDATE
更新列的权限。对于已读取但未修改的列,您只需要特权(例如,对于仅在
子句
中=
赋值SELECT
的右侧引用的列
)。col_name
expr
ON DUPLICATE KEY UPDATE
插入分区表时,您可以控制哪些分区和子分区接受新行。该
PARTITION
子句采用表的一个或多个分区或子分区(或两者)的逗号分隔名称列表。如果给定语句要插入的任何行与INSERT
列出的分区之一不匹配,则
INSERT
语句失败并显示错误Found a row not matching the given partition set。有关更多信息和示例,请参阅
第 19.5 节,“分区选择”。
tbl_name
是应该插入行的表。指定语句为其提供值的列,如下所示:
在表名后提供一个用括号括起来的以逗号分隔的列名列表。在这种情况下,每个命名列的值必须由
VALUES
列表或SELECT
语句提供。如果您没有为
INSERT ... VALUES
或 指定列名列表INSERT ... SELECT
,则表中每一列的值都必须由VALUES
列表或SELECT
语句提供。如果您不知道表中列的顺序,请使用 查找。DESCRIBE
tbl_name
子句通过
SET
名称显式指示列,以及分配给每个列的值。
可以通过多种方式给出列值:
如果未启用严格 SQL 模式,则任何未显式指定值的列都将设置为其默认(显式或隐式)值。例如,如果您指定的列列表未命名表中的所有列,则未命名的列将设置为其默认值。默认值分配在 第 11.5 节,“数据类型默认值”中描述。另见 第 1.7.3.3 节,“对无效数据的约束”。
如果启用了严格的 SQL 模式,如果
INSERT
语句没有为没有默认值的每个列指定显式值,则会生成错误。请参阅 第 5.1.10 节,“服务器 SQL 模式”。如果列列表和
VALUES
列表都为空,则INSERT
创建一行并将每一列设置为其默认值:INSERT INTO tbl_name () VALUES();
如果未启用严格模式,则 MySQL 对没有显式定义默认值的任何列使用隐式默认值。如果启用了严格模式,则如果任何列没有默认值,则会发生错误。
使用关键字
DEFAULT
将列显式设置为其默认值。这使得编写INSERT
为除少数列之外的所有列赋值的语句变得更加容易,因为它使您能够避免编写VALUES
不包含表中每一列的值的不完整列表。否则,您必须提供与列表中每个值对应的列名VALUES
列表。在表达式中,您可以使用 来生成列的默认值 。
DEFAULT(
col_name
)col_name
expr
如果表达式数据类型与列数据类型不匹配,则可能会发生提供列值 的表达式的类型转换 。根据列类型的不同,给定值的转换可能会导致不同的插入值。例如,将字符串'1999.0e-2'
插入INT
、FLOAT
、DECIMAL(10,6)
或YEAR
列会分别插入值1999
、19.9921
、19.992100
或1999
。INT
和YEAR
列中 存储的 值为1999
因为字符串到数字的转换只查看字符串的初始部分,因为它可能被认为是有效的整数或年份。对于FLOAT
和DECIMAL
列,字符串到数字的转换将整个字符串视为有效数值。表达式
expr
可以引用先前在值列表中设置的任何列。例如,您可以这样做,因为 for 的值col2
引用了col1
之前已分配的值:INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
但是下面是不合法的,因为 for 的值是
col1
指col2
,它是在 之后赋值的col1
:INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
AUTO_INCREMENT
包含值 的列发生异常 。因为AUTO_INCREMENT
值是在其他赋值之后生成的,所以AUTO_INCREMENT
对赋值中列的任何引用都会返回一个0
.
INSERT
使用
VALUES
语法的语句可以插入多行。为此,包括多个以逗号分隔的列值列表,列表用括号括起来并以逗号分隔。例子:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
每个值列表必须包含与每行要插入的值一样多的值。以下语句无效,因为它包含一个包含九个值的列表,而不是三个包含三个值的列表:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3,4,5,6,7,8,9);
VALUE
VALUES
在这种情况下是同义词
。既不暗示值列表的数量,也不暗示每个列表的值的数量。无论是单个值列表还是多个列表,并且无论每个列表的值数量如何,都可以使用两者之一。
INSERT
可以使用
ROW_COUNT()
SQL 函数或
mysql_affected_rows()
C API 函数获取
an 的 affected-rows 值
。请参阅第 12.16 节,“信息函数”和
mysql_affected_rows()。
如果您使用INSERT ...
VALUES
包含多个值列表 or
INSERT ...
SELECT
的语句,该语句将返回以下格式的信息字符串:
Records: N1 Duplicates: N2 Warnings: N3
如果您使用的是 C API,则可以通过调用该mysql_info()
函数来获取信息字符串。请参阅mysql_info()。
Records
指示语句处理的行数。(这不一定是实际插入的行数,因为Duplicates
可以为非零。)Duplicates
表示无法插入的行数,因为它们会复制某些现有的唯一索引值。Warnings
指示尝试插入以某种方式出现问题的列值的次数。在以下任何情况下都可能出现警告:
插入
NULL
到已声明的列中NOT NULL
。对于多行INSERT
语句或INSERT INTO ... SELECT
语句,列设置为列数据类型的隐式默认值。这适用0
于数字类型,空字符串 (''
) 适用于字符串类型, “零”值适用于日期和时间类型。INSERT INTO ... SELECT
语句的处理方式与多行插入相同,因为服务器不会检查结果集SELECT
以查看它是否返回单行。(对于单行INSERT
,当NULL
插入到NOT NULL
柱子。相反,该语句因错误而失败。)将数字列设置为位于列范围之外的值。该值被裁剪到范围的最近端点。
'10.34 a'
为数字列 分配一个值,例如。尾随的非数字文本被剥离,剩余的数字部分被插入。如果字符串值没有前导数字部分,则该列设置为0
。将字符串插入超过列最大长度的字符串列(
CHAR
、VARCHAR
、TEXT
或 )。BLOB
该值被截断为列的最大长度。向日期或时间列中插入对于数据类型非法的值。该列被设置为适合该类型的零值。
有关列值 的
INSERT
示例 ,请参阅第 3.6.9 节,“使用 AUTO_INCREMENT”。AUTO_INCREMENT
如果
INSERT
将一行插入到具有一列的表中,您可以使用SQL 函数或C API 函数AUTO_INCREMENT
找到用于该列的值 。LAST_INSERT_ID()
mysql_insert_id()
笔记这两个函数的行为并不总是相同。
INSERT
语句关于AUTO_INCREMENT
列 的行为在第 12.16 节,“信息函数”和 mysql_insert_id()中进一步讨论。
该INSERT
语句支持以下修饰符:
如果使用
DELAYED
修饰符,服务器会将要插入的一行或多行放入缓冲区,然后发出该INSERT DELAYED
语句的客户端可以立即继续。如果该表正在使用中,则服务器保留这些行。当表空闲时,服务器开始插入行,定期检查是否有任何新的表读取请求。如果有,延迟行队列将被挂起,直到表再次空闲。请参阅 第 13.2.5.3 节,“插入延迟语句”。DELAYED
用INSERT ... SELECT
或 忽略INSERT ... ON DUPLICATE KEY UPDATE
。DELAYED
INSERT
对于使用访问表或触发器的函数,或者从函数或触发器调用 的 an,也将被忽略 。笔记从 MySQL 5.6.6 开始,
INSERT DELAYED
已弃用;希望在未来的版本中将其删除。使用INSERT
(withoutDELAYED
) 代替。如果您使用
LOW_PRIORITY
修饰符,则执行INSERT
会延迟,直到没有其他客户端从表中读取。这包括在现有客户正在阅读和INSERT LOW_PRIORITY
声明正在等待时开始阅读的其他客户。因此,对于发出INSERT LOW_PRIORITY
语句的客户端来说,在读取密集的环境中等待很长时间(甚至永远)是可能的。(这与 相反INSERT DELAYED
,后者让客户端立即继续。)LOW_PRIORITY
仅影响仅使用表级锁定的存储引擎(例如MyISAM
、MEMORY
和MERGE
)。笔记LOW_PRIORITY
通常不应与MyISAM
表一起使用,因为这样做会禁用并发插入。请参阅 第 8.11.3 节,“并发插入”。如果您指定
HIGH_PRIORITY
,如果服务器是使用该选项启动的,它将覆盖该选项的效果--low-priority-updates
。它还会导致不使用并发插入。请参阅 第 8.11.3 节,“并发插入”。HIGH_PRIORITY
仅影响仅使用表级锁定的存储引擎(例如MyISAM
、MEMORY
和MERGE
)。如果使用修饰符,则忽略执行语句
IGNORE
时发生的错误 。INSERT
例如,如果没有IGNORE
,复制表中现有UNIQUE
索引或PRIMARY KEY
值的行会导致重复键错误并且语句被中止。使用IGNORE
,该行被丢弃并且不会发生错误。忽略的错误可能会生成警告,但重复键错误不会。IGNORE
对于未找到与给定值匹配的分区的分区表的插入具有类似的效果。如果没有IGNORE
,此类INSERT
语句将因错误而中止。使用时INSERT IGNORE
,对于包含不匹配值的行,插入操作会静默失败,但会插入匹配的行。有关示例,请参阅 第 19.2.2 节,“LIST 分区”。IGNORE
如果未指定 ,将触发错误的数据转换将中止语句。使用IGNORE
,将无效值调整为最接近的值并插入;产生警告但语句不会中止。您可以使用mysql_info()
C API 函数确定实际插入表中的行数。您可以使用
REPLACE
instead ofINSERT
来覆盖旧行。REPLACE
对应INSERT IGNORE
于处理包含重复旧行的唯一键值的新行:新行替换旧行而不是被丢弃。请参阅 第 13.2.8 节,“REPLACE 语句”。如果您指定
ON DUPLICATE KEY UPDATE
,并且插入的行会导致UNIQUE
索引或中出现重复值PRIMARY KEY
,UPDATE
则会出现旧行。如果该行作为新行插入,则每行的 affected-rows 值为 1;如果更新现有行,则为 2;如果现有行设置为其当前值,则为 0。如果在连接到mysqldCLIENT_FOUND_ROWS
时将标志指定给mysql_real_connect()
C API 函数,并且将现有行设置为其当前值,则受影响的行值为 1(而不是 0)。参见第 13.2.5.2 节,“INSERT ... ON DUPLICATE KEY UPDATE 语句”。
影响使用存储引擎的分区表的INSERT
语句(例如
MyISAM
采用表级锁的语句)仅锁定实际插入行的那些分区。(对于诸如InnoDB
使用行级锁定的存储引擎,不会发生分区锁定。)有关更多信息,请参阅
第 19.6.4 节,“分区和锁定”。