更新时间:2024-12-30 GMT+08:00

UPDATE

功能描述

更新表中的数据。UPDATE修改满足条件的所有行中指定的字段值,WHERE子句声明条件,SET子句指定的字段会被修改,没有出现的字段则保持它们的原值。

注意事项

  • 要修改表,用户必须对该表有UPDATE权限。
  • 对expression或condition条件里涉及到的任何表要有SELECT权限。
  • 不允许对表的分布列(distribute column)进行修改。
  • 对于列存表,暂时不支持RETURNING子句。
  • 列存表不支持结果不确定的更新(non-deterministic update)。试图对列存表用多行数据更新一行时会报错。
  • 列存表的更新操作,旧记录空间不会回收,需要执行VACUUM FULL table_name进行清理。
  • UPDATE操作频繁的表不建议创建为复制表。
  • 对于列存表,支持轻量化UPDATE操作。轻量化UPDATE只重写更新列,减少空间使用量。列存轻量化UPDATE通过GUC参数enable_light_colupdate控制是否开启,默认关闭。
  • 列存轻量化UPDATE在以下场景不能使用:更新索引列,更新主键列,更新分区列,更新PCK列和在线扩容,会自动转化为普通UPDATE方式。
  • 列存轻量化UPDATE与后台列存AUTOVACUUM并发会小概率报错,可以通过ALTER TABLE设置表级参数enable_column_autovacuum_garbage为off来避免。需要注意的是设置表级参数enable_column_autovacuum_garbage为off会关闭该表的后台列存AUTOVACUUM。
  • 避免使用UPDATE/DELETE大批量刷新和删除数据,考虑使用TRUNCATE PARTITION/DROP PARTITION代替。
  • 避免UPDATE/UPSERT并发更新同一张列存表。
  • 更多开发设计规范参见总体开发设计规范

语法格式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    UPDATE [/*+ plan_hint */] [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    [ PARTITION ( partition_name ) | PARTITION FOR ( partition_key_value [, ...] ) ]
SET {column_name = { expression | DEFAULT } 
    |( column_name [, ...] ) = {( { expression | DEFAULT } [, ...] ) |sub_query }}[, ...]
    [ FROM from_list] [ WHERE condition ]
    [ RETURNING {* 
                | {output_expression [ [ AS ] output_name ]} [, ...] }];

where sub_query can be:
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
{ * | {expression [ [ AS ] output_name ]} [, ...] }
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY grouping_element [, ...] ]
[ HAVING condition [, ...] ]

参数说明

  • plan_hint子句

    以/*+ */的形式在关键字后,用于对指定语句块生成的计划进行hint调优,详细用法请参见使用Plan Hint进行调优

  • table_name

    要更新的表名,可以使用模式修饰。

    取值范围:已存在的表名称。

  • alias

    目标表的别名。

    取值范围:字符串,符合标识符命名规范。

  • partition_name

    分区名。仅8.2.1及以上集群版本支持该选项。

    取值范围:已存在的分区名。

  • partition_key_value

    分区键值。

    通过PARTITION FOR ( partition_key_value [, ...] )子句指定的这一组值,可以唯一确定一个分区。

    取值范围:需要进行重命名分区的分区键的取值范围。

  • column_name

    要修改的字段名。

    支持使用目标表的表名加字段名来引用这个字段。例如:

    1
    UPDATE foo SET foo.col_name = 'GaussDB';
    

    支持使用目标表的别名加字段名来引用这个字段。例如:

    1
    UPDATE foo AS f SET f.col_name = 'GaussDB';
    

    取值范围:已存在的字段名。

  • expression

    赋给字段的值或表达式。

  • DEFAULT

    用对应字段的缺省值填充该字段。

    如果没有缺省值,则为NULL。

  • sub_query

    子查询。

    使用同一数据库里其他表的信息来更新一个表可以使用子查询的方法。其中SELECT子句具体介绍请参考SELECT

  • from_list

    一个表的表达式列表,允许在WHERE条件里使用其他表的字段。与在一个SELECT语句的FROM子句里声明表列表类似。

    目标表绝对不能出现在from_list里,除非在使用一个自连接(此时它必须以from_list的别名出现)。

  • condition

    一个返回boolean类型结果的表达式。只有这个表达式返回true的行才会被更新。

  • output_expression

    在所有需要更新的行都被更新之后,UPDATE命令用于计算返回值的表达式。

    取值范围:使用任何table以及FROM中列出的表的字段。*表示返回所有字段。

  • output_name

    字段的返回名称。

示例

直接更新所有记录的值:

1
UPDATE reason SET r_reason_sk = r_reason_sk * 2;

不含WHERE子句表示更新所有r_reason_sk的值:

1
UPDATE reason SET r_reason_sk = r_reason_sk + 100;

将表reason中r_reason_desc为reason2的r_reason_sk重新定义:

1
UPDATE reason SET r_reason_sk = 5 WHERE r_reason_desc = 'reason2';

将表reason中r_reason_sk为2的r_reason_sk重新定义:

1
UPDATE reason SET r_reason_sk = r_reason_sk + 100 WHERE r_reason_sk = 2;

将表reason中r_reason_sk大于2的课程编号全部重新定义:

1
UPDATE reason SET r_reason_sk = 201 WHERE r_reason_sk > 2;

可以在一个UPDATE命令中更新多个字段,方法是在SET子句中列出更多赋值,比如:

1
UPDATE reason SET r_reason_sk = 5, r_reason_desc = 'reason5' WHERE r_reason_id = 'fourth'; 

更新分区表test_range_row的指定分区p1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
CREATE TABLE test_range_row(a int, d int)
DISTRIBUTE BY hash(a) PARTITION BY RANGE(d)
(
    PARTITION p1 values LESS THAN (60),
    PARTITION p2 values LESS THAN (75),
    PARTITION p3 values LESS THAN (90),
    PARTITION p4 VALUES LESS THAN (maxvalue)
);
INSERT OVERWRITE INTO test_range_row PARTITION(p1) VALUES(55,51);
INSERT OVERWRITE INTO test_range_row PARTITION(p3) VALUES(85,80);

UPDATE test_range_row PARTITION(p1) SET d = 41;