替换[low_priority | delayed] [into]tbl_name(分区(partition_name[,partition_name] ...)] [(col_name[,col_name]…)]{{values | value} (value_list) ((value_list)]…|值row_constructor_list} replace [low_priority | delayed] [into]tbl_name(分区(partition_name[,partition_name]…)]assignment_list替换[low_priority | delayed] [into]tbl_name(分区(partition_name[,partition_name] ...)] [(col_name[,col_name)]{选择…|表table_name}价值:{expr|默认}value_list:价值[,价值)……row_constructor_list:行(value_list)、行(value_list)][……]赋值:col_name=价值assignment_list:赋值[,赋值)……
取代
作品一模一样插入
,除非表中的旧行与a的新行具有相同的值主键
或者一个独特的
索引后,在插入新行之前删除旧行。看到第13.2.6节,“INSERT语句”.
取代
是MySQL对SQL标准的扩展。它要么插入,要么删除和插入。对于标准sql的另一个MySQL扩展——插入或更新查查第13.2.6.2节,“插入…关于重复密钥更新声明".
延迟
insert和replace在MySQL 5.6中已弃用。在MySQL 8.0中,延迟
不支持。属性,服务器识别但忽略延迟
关键字,将替换处理为非延迟替换,并生成ER_WARN_LEGACY_SYNTAX_CONVERTED
警告:不再支持REPLACE DELAYED。语句被转换为REPLACE.的延迟
关键字计划在未来的版本中删除。释放。
属性中指定的值获取所有列的值取代
声明。任何缺失的列都被设置为它们的默认值,就像以下情况一样插入
.不能引用当前行的值并在新行中使用它们。如果你使用赋值,例如集
,对右侧列名的引用被视为col_name
=col_name
+ 1违约(
,赋值等于col_name
)集
.col_name
=违约(col_name
) + 1
在MySQL 8.0.19及以后版本中,您可以指定列值取代
尝试使用值行()
.
如果显式替换生成的列,则唯一允许的值是默认的
.有关生成的列的信息,请参见第13.1.20.8节,“创建表和生成列”.
取代
控件支持显式分区选择分区
子句,带有分区、子分区或两者之间以逗号分隔的名称列表。与插入
,如果无法将新行插入任何这些分区或子分区中,则取代
语句失败并报错找到与给定分区集不匹配的行.有关更多信息和示例,请参见第24.5节,“分区选择”.
的取代
语句返回一个计数,以指示受影响的行数。这是删除和插入的行之和。如果一个单行的计数是1取代
,插入一行,没有删除行。如果计数大于1,则在插入新行之前删除一个或多个旧行。如果表包含多个惟一索引,并且新行在不同惟一索引中重复不同旧行的值,则单个行可以替换多个旧行。
受影响的行数可以很容易地确定是否取代
只添加一行或它是否也替换任何行:检查计数是否为1(添加)或更大(替换)。
如果使用C API,则可以使用mysql_affected_rows ()
函数。
您不能在子查询中替换到一个表并从同一表中进行选择。
尝试将新行插入到表中
当插入失败时,因为主键或唯一索引出现重复键错误:
从表中删除具有重复键值的冲突行
请再次将新行插入表中
在密钥重复错误的情况下,存储引擎可能会执行取代
作为更新而不是删除加插入,但语义是一样的。除了存储引擎增量方式的不同之外,用户看不到其他影响Handler_
状态变量。xxx
因为结果是取代……选择
语句依赖于选择
并且这个顺序不能总是得到保证,当记录源和副本的这些语句分叉时是可能的。由于这个原因,取代……选择
对于基于语句的复制,语句被标记为不安全的。当使用基于语句的模式时,这样的语句会在错误日志中产生一个警告,并在使用基于行的格式时被写入二进制日志混合
模式。另请参阅第17.2.1.1节,“基于语句和基于行复制的优缺点”.
MySQL 8.0.19及以后版本的支持表格
以及选择
与取代
,就像它与插入
.看到第13.2.6.1节,“插入…SELECT语句”,获取更多信息和例子。
在修改未分区的现有表以适应分区时,或者在修改已分区表的分区时,可以考虑修改表的主键(参见第24.6.1节,“分区键、主键和唯一键”).你应该知道,如果你这样做,结果取代
语句可能会受到影响,就像修改非分区表的主键一样。考虑下面创建的表创建表
声明:
创建表test (id INT UNSIGNED NOT NULL AUTO_INCREMENT, data VARCHAR(64) DEFAULT NULL, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id));
当我们创建这个表并运行mysql客户端中显示的语句时,结果如下:
mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');mysql> SELECT * FROM test;+----+------+---------------------+ | id | | ts的数据 | +----+------+---------------------+ | 新| 1 | 2014-08-20 18:47:42 | +----+------+---------------------+ 1行集(0.00秒)
现在我们创建第二个表,与第一个表几乎相同,除了主键现在覆盖了2列,如下所示(强调文本):
创建表test2 (id INT UNSIGNED NOT NULL AUTO_INCREMENT, data VARCHAR(64) DEFAULT NULL, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,主键id, ts);
当我们继续test2
相同的两个取代
就像我们对原始的表述一样测试
表中,我们得到一个不同的结果:
mysql> REPLACE INTO test2 VALUES(1, '老','2014-08-20 18:47:00');mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');mysql> SELECT * FROM test2;+----+------+---------------------+ | id | | ts的数据 | +----+------+---------------------+ | 旧1 | | 2014-08-20 18:47:00 | | 1 | | 2014-08-20 18:47:42 | +----+------+---------------------+ 2行集(0.00秒)
这是由于这样一个事实,当运行test2
,id
和ts
对于要替换的行,列值必须与现有行的值匹配;否则,插入一行。