10bet网址
MySQL 8.0参考手册
相关的文档10bet官方网站 本手册下载 本手册摘录

13.2.9替换语句

替换[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_namecol_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 ()函数。

您不能在子查询中替换到一个表并从同一表中进行选择。

MySQL使用以下算法取代(和加载数据…取代):

  1. 尝试将新行插入到表中

  2. 当插入失败时,因为主键或唯一索引出现重复键错误:

    1. 从表中删除具有重复键值的冲突行

    2. 请再次将新行插入表中

在密钥重复错误的情况下,存储引擎可能会执行取代作为更新而不是删除加插入,但语义是一样的。除了存储引擎增量方式的不同之外,用户看不到其他影响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,idts对于要替换的行,列值必须与现有行的值匹配;否则,插入一行。