REPLACE INTO

REPLACE INTO — 在主键约束冲突时更新表中的行

Synopsis

[ WITH [ RECURSIVE ] with_query [, ...] ]
REPLACE INTO table_name [ AS alias ] [ ( column_name [, ...] ) ]
    [ OVERRIDING { SYSTEM | USER } VALUE ]
    VALUES ( { expression | DEFAULT } [, ...] ) [, ...]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

描述

REPLACEINSERT 的工作方式完全相同, 唯一的区别是,如果表中已存在与新行具有相同值的旧行(针对主键索引), 则在插入新行之前将删除旧行。

Note

仅当表具有主键索引时,REPLACE 才有意义(不支持唯一索引)。 否则,它将等同于INSERT,因为没有索引可用于确定新行是否重复另一行。

所有列的值都来自于REPLACE语句中指定的值。任何缺少的列都将设置为默认值,就像INSERT一样。

要替换表中的行,必须同时具有INSERTUPDATE权限。

参数

替换

本节介绍仅在替换新行时可能使用的参数。

with_query

WITH子句允许您指定一个或多个子查询,可以通过名称在REPLACE查询中引用。 有关详细信息,请参见Section 8.8SELECT

table_name

table_name的名称(可选模式限定符),表示现有表。

alias

table_name的替代名称。 提供别名时,它完全隐藏表的实际名称。

column_name

table_name中的列名。 如果需要,列名可以使用子字段名或数组下标进行限定。 (仅替换复合列的某些字段会使其他字段为空。)

OVERRIDING SYSTEM VALUE

如果指定了这个子句,则为标识列提供的任何值都将覆盖默认的序列生成值。

对于定义为GENERATED ALWAYS的标识列,在未指定 OVERRIDING SYSTEM VALUEOVERRIDING 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命令后,将返回以下形式的命令标记:

REPLACE oid count

countoid的含义与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