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命令后,将返回以下形式的命令标记:
REPLACEoidcount
   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。