REPLACE¶
REPLACE 是一个数据操作语句,向表中插入数据,主键冲突时先删除旧记录再插入新记录。支持 VALUES、SET 和 SELECT 三种语法形式,以及 LOW_PRIORITY 和 DELAYED 修饰符。
语法描述¶
REPLACE 是一个数据操作语句,作用是向表中插入数据。如果表中已经存在相同主键的记录,则会先删除该记录,然后再插入新数据。如果表中不存在符合条件的记录,则直接插入新数据。
REPLACE 通常在具有主键约束的表中使用。
REPLACE语句要求表中必须存在主键,用于判断是否已存在相同记录。MatrixOne 仅在主键冲突时触发替换行为;二级唯一索引冲突会抛出 ERROR 1062,不会触发 REPLACE 语义。使用
REPLACE语句插入新记录时,如果已存在相同主键的记录,旧记录将被删除后插入新记录,这可能导致自增列的值发生变化。
语法结构¶
REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
{ VALUES(value_list)
|
VALUES row_constructor_list
}
REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
SET assignment_list
REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
SELECT ...
value:
{expr | DEFAULT}
value_list:
value [, value] ...
row_constructor_list:
ROW(value_list)
assignment:
col_name = value
assignment_list:
assignment [, assignment] ...
参数释义¶
REPLACE 语句用于向表中插入数据或更新已存在的数据。语法有三种形式:基于列名和 VALUES 的插入形式、基于 SET 子句的更新形式、以及从查询结果插入的 SELECT 形式。
可选的 LOW_PRIORITY 修饰符会延迟执行直至没有其他客户端正在读取该表。DELAYED 仅做 MySQL 兼容性接受,在 MatrixOne 中不产生实际效果。
以下是各参数的说明:
LOW_PRIORITY | DELAYED: 可选修饰符。LOW_PRIORITY会降低语句的执行优先级;DELAYED做兼容性接受但不产生实际效果。INTO: 可选关键字,表示向哪张表插入或更新数据。tbl_name: 要插入或更新数据的表名。PARTITION: 可选子句,指定目标分区。partition_name为分区名,支持多个分区以逗号分隔。col_name: 可选参数,要插入或更新的列名。在插入形式和 SELECT 形式中指定涉及的列;在更新形式中指定要更新的列。value: 要插入或更新的值,可以是表达式(expr)或默认值(DEFAULT)。value_list: 一组要插入的值,多个值以逗号分隔。row_constructor_list: 由ROW(value_list)构成的行值列表,用于插入多行数据。assignment: 列名与其对应值的关联对,用于 SET 更新形式。assignment_list: 多个assignment的逗号分隔列表。SELECT ...: 从查询结果中读取数据并插入目标表。SELECT 返回的列必须与目标表的列兼容。
备注
VALUES 形式中,
VALUES后跟value_list表示插入一行数据,VALUES后跟row_constructor_list表示插入多行数据。SET 形式使用
SET assignment_list来指定要插入或更新的列和对应的值。SELECT 形式从查询结果中获取数据并插入目标表。
示例¶
VALUES 形式¶
DROP DATABASE IF EXISTS dbreplace;
CREATE DATABASE dbreplace;
USE dbreplace;
CREATE TABLE names(id INT PRIMARY KEY, name VARCHAR(255), age INT);
-- 插入一行数据
REPLACE INTO names(id, name, age) VALUES(1, 'Abby', 24);
SELECT * FROM names;
-- 使用 REPLACE 更新 id=1 的记录
REPLACE INTO names(id, name, age) VALUES(1, 'Bobby', 25);
SELECT * FROM names;
-- 多行插入
REPLACE INTO names(id, name, age) VALUES
ROW(3, 'Dana', 30),
ROW(4, 'Eve', 28);
SELECT * FROM names ORDER BY id;
DROP DATABASE dbreplace;
SET 形式¶
DROP DATABASE IF EXISTS dbreplace;
CREATE DATABASE dbreplace;
USE dbreplace;
CREATE TABLE names(id INT PRIMARY KEY, name VARCHAR(255), age INT);
-- 插入一行数据
REPLACE INTO names SET id = 2, name = 'Ciro';
SELECT * FROM names;
-- 更新 id=2 的记录
REPLACE INTO names SET id = 2, name = 'Ciro', age = 17;
SELECT * FROM names;
DROP DATABASE dbreplace;
SELECT 形式¶
DROP DATABASE IF EXISTS dbreplace;
CREATE DATABASE dbreplace;
USE dbreplace;
CREATE TABLE source(id INT PRIMARY KEY, val VARCHAR(50));
INSERT INTO source VALUES (1, 'alpha'), (2, 'beta'), (3, 'gamma');
CREATE TABLE target(id INT PRIMARY KEY, val VARCHAR(50));
INSERT INTO target VALUES (1, 'old_one');
-- 将 source 中 id>1 的行 REPLACE 到 target,id=1 的行会被更新
REPLACE INTO target(id, val) SELECT id, val FROM source WHERE id > 1;
SELECT * FROM target ORDER BY id;
DROP DATABASE dbreplace;
LOW_PRIORITY 修饰符¶
DROP DATABASE IF EXISTS dbreplace;
CREATE DATABASE dbreplace;
USE dbreplace;
CREATE TABLE products(id INT PRIMARY KEY, name VARCHAR(100), price DECIMAL(10,2));
REPLACE LOW_PRIORITY INTO products VALUES (1, 'Widget', 9.99);
SELECT * FROM products;
DROP DATABASE dbreplace;
限制¶
REPLACE语句要求表中必须存在主键,用于判断是否已存在相同记录。MatrixOne 仅检测主键冲突;二级唯一索引冲突会抛出 ERROR 1062,不会触发 REPLACE 语义。MySQL 8.0 同时处理主键和唯一索引冲突。使用
REPLACE语句插入新记录时,如果已存在相同主键的记录,旧记录将被删除后插入新记录,这可能导致自增列的值发生变化。DELAYED仅做 MySQL 兼容性接受,在 MatrixOne 中不会产生实际效果,语句会立即执行。