REPLACE
语法
REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [PARTITION (partition_list)] [(col,...)] {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
或:
REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [PARTITION (partition_list)] SET col={expr | DEFAULT}, ...
或:
REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [PARTITION (partition_list)] [(col,...)] SELECT ...
描述
REPLACE
工作方式完全等同于
INSERT
语句,除了表中行的PRIMARY KEY
或UNIQUE
索引键值重复时,REPLACE会先删除旧值,然后插入新值。如果表中有多个UNIQUE
键,可能插入一行时会出现多个冲突,这种情况下,所有冲突的行都会被更新。
表名可使用db_name
.tbl_name
格式来指定,如果指定格式为tbl_name
,则使用默认数据库(见Identifier Qualifiers)。因此,REPLACE ... SELECT
可以在不同数据库之间拷贝数据。
REPLACE基本工作方式大致如下:
BEGIN; SELECT 1 FROM t1 WHERE key=# FOR UPDATE; IF found-row DELETE FROM t1 WHERE key=# ; INSERT INTO t1 VALUES (...); END IF END;
上述过程可替换为:
REPLACE INTO t1 VALUES (...)
REPLACE
语句是MariaDB/MySQL对标准SQL的扩展。它可以插入数据、删除数据再插入数据。除此之外,MariaDB/MySQL对于重复值冲突的处理方式还有几种扩展,见IGNORE和INSERT ON DUPLICATE KEY UPDATE。
需要注意的是,如果表中没有PRIMARY KEY
或
UNIQUE
索引,那么REPLACE
语句和INSERT
语句完全等价,因为不会检测新行和表中已存在的行是否重复。
如果使用SET
子句赋值,它不能从当前行获取数据作为新行的数据源。例如,使用赋值语句'SET col = col + 1'
,则右边引用的字段col的值不是某行中的col,而是使用默认值DEFAULT(col)
,因此该赋值语句等价于:'SET col = DEFAULT(col) + 1'
。注意,当字段没有指定默认值时,DEFAULT()
的值为0或null。
要使用REPLACE
,必须拥有表的INSERT
和DELETE
权限。
在使用REPLACE
语句之前,有几个需要注意的陷进:
- 如果表中有
AUTO_INCREMENT
字段,将为该字段分配新值。 - 如果有外键引用,则
REPLACE
会激活ON DELETE
行为。 - 如果
REPLACE
只是简单的插入数据,它只会触发INSERT
触发器,如果它更新了已有数据,则会触发DELETE
触发器和INSERT
触发器。详细内容见:Trigger Overview。
如果以上某些操作是你不想发生的,可以考虑使用INSERT ... ON DUPLICATE KEY UPDATE
来替代REPLACE
语句。
MariaDB starting with 10.0
PARTITION子句是从MariaDB 10.0中开始引入的新特性,详细信息见Partition Pruning and Selection。
See also
- HIGH_PRIORITY and LOW_PRIORITY clauses
- INSERT DELAYED for details on the
DELAYED
clause