REPLACE INTO — 在主键约束冲突时更新表中的行
[ WITH [ RECURSIVE ]with_query
[, ...] ] REPLACE INTOtable_name
[ ASalias
] [ (column_name
[, ...] ) ] [ OVERRIDING { SYSTEM | USER } VALUE ] VALUES ( {expression
| DEFAULT } [, ...] ) [, ...] [ RETURNING * |output_expression
[ [ AS ]output_name
] [, ...] ]
REPLACE
和 INSERT
的工作方式完全相同,
唯一的区别是,如果表中已存在与新行具有相同值的旧行(针对主键索引),
则在插入新行之前将删除旧行。
仅当表具有主键索引时,REPLACE
才有意义(不支持唯一索引)。
否则,它将等同于INSERT,因为没有索引可用于确定新行是否重复另一行。
所有列的值都来自于REPLACE语句中指定的值。任何缺少的列都将设置为默认值,就像INSERT一样。
要替换表中的行,必须同时具有INSERT
和UPDATE
权限。
本节介绍仅在替换新行时可能使用的参数。
with_query
WITH
子句允许您指定一个或多个子查询,可以通过名称在REPLACE
查询中引用。
有关详细信息,请参见Section 8.8和SELECT。
table_name
table_name
的名称(可选模式限定符),表示现有表。
alias
table_name
的替代名称。
提供别名时,它完全隐藏表的实际名称。
column_name
table_name
中的列名。
如果需要,列名可以使用子字段名或数组下标进行限定。
(仅替换复合列的某些字段会使其他字段为空。)
OVERRIDING SYSTEM VALUE
如果指定了这个子句,则为标识列提供的任何值都将覆盖默认的序列生成值。
对于定义为GENERATED ALWAYS
的标识列,在未指定
OVERRIDING SYSTEM VALUE
或OVERRIDING USER
VALUE
的情况下插入显式值(除DEFAULT
外)
是错误的。(对于定义为GENERATED BY DEFAULT
的标识列,
OVERRIDING SYSTEM VALUE
是正常行为,指定它不起作用,
但是LightDB将其作为扩展允许。)
OVERRIDING USER VALUE
如果指定了这个子句,则将忽略为标识列提供的任何值,并应用默认的序列生成值。
例如,在表之间复制值时,可以使用这个子句。写入
INSERT INTO tbl2 OVERRIDING USER VALUE SELECT * FROM tbl1
将从tbl1
复制所有不是tbl2
的标识列的列,
而tbl2
的标识列的值将由与tbl2
相关联的序列生成。
expression
要分配给相应列的表达式或值。
DEFAULT
相应的列将填充其默认值。标识列将填充由相关序列生成的新值。 对于生成的列,虽然允许指定此选项,但它只是指定从其生成表达式计算列的正常行为。
output_expression
在每行插入或更新后由REPLACE
命令计算并返回的表达式。
表达式可以使用table_name
指定的表的任何列名。
写入*
以返回所插入或更新的行的所有列。
output_name
用于返回列的名称。
成功完成REPLACE
命令后,将返回以下形式的命令标记:
REPLACEoid
count
count
和oid
的含义与INSERT
命令相同。
如果指定的表是分区表,则每行将路由到相应的分区并插入其中。 如果指定的表是分区,则如果输入行中有一行违反了分区约束,则会出现错误。
考虑以下CREATE TABLE
语句创建的表:
CREATE TABLE test ( id INT NOT NULL, name CHAR(16), age INT DEFAULT 0, PRIMARY KEY(id) );
当我们创建这个表并在ltsql客户端中运行以下语句时,结果如下所示:
lightdb@testdb=# REPLACE INTO test VALUES (1, 'Old name', '18'); INSERT 0 1 lightdb@testdb=# REPLACE INTO test VALUES (1, 'New name'); INSERT 0 1 lightdb@testdb=# SELECT * FROM test; id | name | age ----+------------------+----- 1 | New name | 0 (1 row)
考虑以下CREATE TABLE
语句创建的表:
CREATE TABLE test ( id INT NOT NULL, name CHAR(16), seq SERIAL, PRIMARY KEY(id) );
当我们创建这个表并在ltsql客户端中运行以下语句时,由于主键约束冲突,'seq'的值变为了4:
lightdb@testdb=# REPLACE INTO test VALUES (1, 'Old name1'), (2, 'Old name2'); INSERT 0 2 lightdb@testdb=# SELECT * FROM test; id | name | seq ----+------------------+----- 1 | Old name1 | 1 2 | Old name2 | 2 (2 rows) lightdb@testdb=# REPLACE INTO test VALUES (1, 'New name'); INSERT 0 1 lightdb@testdb=# SELECT * FROM test; id | name | seq ----+------------------+----- 2 | Old name2 | 2 1 | New name | 4 (2 rows)
REPLACE
是LightDB对SQL标准的扩展。它可以插入、删除并插入。只有当数据库的语法兼容类型为mysql时,才支持REPLACE
。
详情请参见lightdb_syntax_compatible_type。