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 中不产生实际效果。

以下是各参数的说明:

  1. LOW_PRIORITY | DELAYED: 可选修饰符。LOW_PRIORITY 会降低语句的执行优先级;DELAYED 做兼容性接受但不产生实际效果。

  2. INTO: 可选关键字,表示向哪张表插入或更新数据。

  3. tbl_name: 要插入或更新数据的表名。

  4. PARTITION: 可选子句,指定目标分区。partition_name 为分区名,支持多个分区以逗号分隔。

  5. col_name: 可选参数,要插入或更新的列名。在插入形式和 SELECT 形式中指定涉及的列;在更新形式中指定要更新的列。

  6. value: 要插入或更新的值,可以是表达式(expr)或默认值(DEFAULT)。

  7. value_list: 一组要插入的值,多个值以逗号分隔。

  8. row_constructor_list: 由 ROW(value_list) 构成的行值列表,用于插入多行数据。

  9. assignment: 列名与其对应值的关联对,用于 SET 更新形式。

  10. assignment_list: 多个 assignment 的逗号分隔列表。

  11. 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 中不会产生实际效果,语句会立即执行。