表中插入数据后,可以使用 UPDATE ... SET ... 语句更新表的行记录。
UPDATE 用于更新表数据,可以更新一个字段或者多个字段。
语法如下:
UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
SET { column_name = { expression | DEFAULT } |
( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
( column_name [, ...] ) = ( sub-SELECT )
} [, ...]
[ FROM from_list ]
[ WHERE condition ]
参数说明:
table_name: 要更新的表的名称(可以是模式限定的)。如果在表名前指定了ONLY,只会更新所提及表中的匹配行。如果没有指定ONLY,会递归地更新所提及表以及子表中所匹配的行。alias: 目标表的一个替代名称。在提供了一个别名时,它会完全隐藏表的真实名称。例如,给定UPDATE foo AS f,UPDATE语句的剩余部分必须用f而不是foo来引用该表。column_name:table_name所指定的表的一列的名称。如果需要,该列名可以用一个子域名称或者数组下标限定。不要在目标列的说明中包括表的名称,例如UPDATE table_name SET table_name.col = 1是非法的。expression: 要被赋值给该列的一个表达式。该表达式可以使用该表中这一列或者其他列的旧值。DEFAULT: 将该列设置为它的默认值(如果没有为它指定默认值表达式,默认值将会为NULL)。sub-SELECT: 一个SELECT子查询,它产生和在它之前的圆括号中列列表中一样多的输出列。被执行时,该子查询必须得到不超过一行。如果它得到一行,其列值会被赋予给目标列。如果它得不到行,NULL值将被赋予给目标列。该子查询可以引用被更新表中当前行的旧值。from_list: 表表达式的列表,允许来自其他表的列出现在WHERE条件和更新表达式中。这类似于可以在SELECT语句的FROM子句中指定的表列表。注意目标表不能出现在from_list中,除非你想做自连接(这种情况下它必须以别名出现在from_list中)。condition: 一个返回boolean类型值的表达式。让这个表达式返回true的行将会被更新。
示例
tbase_insert 表结构如下:
tdsql=#\d tbase_insert;
Table "public.tbase_insert"
Column | Type | Collation | Nullable | Default
-----------+---------+-----------+----------+------------
id | numeric | | not null |
name | text | | not null |
value | numeric | | |
create_ts | date | | not null | CURRENT_DATE
Indexes:
"tbase_insert_pkey" PRIMARY KEY, btree (id)
"uniq_idx_value" UNIQUE, btree (value)
1、更新 tbase_insert 表中 create_ts 列的所有值。
tdsql=# set nls_date_format to 'YYYY-MM-DD';
SET
tdsql=# select * from tbase_insert;
id | name | value | create_ts
----+---------------+-------+------------
1 | tbase | 100 | 2024-03-02
2 | tbase | 101 | 2024-03-02
4 | TDSQL PG | 103 | 2024-03-02
5 | TDSQL PG好 | 104 | 2024-03-02
3 | TDSQL PG Good | 102 | 1999-01-01
6 | tbase | 105 | 2024-03-02
(6 rows)
tdsql=# UPDATE tbase_insert SET create_ts = '2022-1-1';
UPDATE 6
tdsql=# select * from tbase_insert;
id | name | value | create_ts
----+---------------+-------+------------
1 | tbase | 100 | 2022-01-01
2 | tbase | 101 | 2022-01-01
4 | TDSQL PG | 103 | 2022-01-01
5 | TDSQL PG好 | 104 | 2022-01-01
3 | TDSQL PG Good | 102 | 2022-01-01
6 | tbase | 105 | 2022-01-01
(6 rows)
2、 更新部分记录。
在更新表数据时,要注意控制更新量不要太大,否则可能会产生大事务导致执行失败。可以只更新部分记录,通过添加 WHERE 关键字来控制范围。
对 value 值为 100 的所有列,将其值更新为 value+10
tdsql=# UPDATE tbase_insert SET value = value+10 where value = 100;
UPDATE 1
tdsql=# select * from tbase_insert;
id | name | value | create_ts
----+---------------+-------+------------
2 | tbase | 101 | 2022-01-01
4 | TDSQL PG | 103 | 2022-01-01
5 | TDSQL PG好 | 104 | 2022-01-01
3 | TDSQL PG Good | 102 | 2022-01-01
6 | tbase | 105 | 2022-01-01
1 | tbase | 110 | 2022-01-01
(6 rows)
tbase_insert 表中 更新 id = 3 所在行的 name 列的值为 tbase ok。
tdsql=# UPDATE tbase_insert SET name = 'tbase ok' WHERE id = 3;
UPDATE 1
tdsql=# select * from tbase_insert;
id | name | value | create_ts
----+------------+-------+------------
2 | tbase | 101 | 2022-01-01
4 | TDSQL PG | 103 | 2022-01-01
5 | TDSQL PG好 | 104 | 2022-01-01
6 | tbase | 105 | 2022-01-01
1 | tbase | 110 | 2022-01-01
3 | tbase ok | 102 | 2022-01-01
(6 rows)
3、 唯一性约束冲突。
当表上有唯一性约束时,更新为相同的记录,系统会报错,如,tbase_insert 表中 id 为主键。
tdsql=# select * from tbase_insert;
id | name | value | create_ts
----+------------+-------+------------
2 | tbase | 101 | 2022-01-01
4 | TDSQL PG | 103 | 2022-01-01
5 | TDSQL PG好 | 104 | 2022-01-01
6 | tbase | 105 | 2022-01-01
1 | tbase | 110 | 2022-01-01
3 | tbase ok | 102 | 2022-01-01
(6 rows)
tdsql=# UPDATE tbase_insert SET id=3 where value = 105;
ERROR: (23505) duplicate key value violates unique constraint "tbase_insert_pkey"
DETAIL: Key (id)=(3) already exists.
说明:
在分布式TDSQL PG中,首列默认为分布键,因此报错信息为:
ERROR: (42P10) Distributed column "ID" can't be updated in current version
将 value = 105 这一行记录的 id 改为 3,会和当前 id = 3 的记录冲突。
4、 多表关联更新数据。
示例中找到 update_table 中 i 列和 src_table 中 i 列相同的记录,将 update_table 的 j 列值更新为 src_table 对应记录的 j 列值。
tdsql=# create table update_table(i int, j int);
CREATE TABLE
tdsql=# insert into update_table values (1,1);
INSERT 0 1
tdsql=# create table src_table(i int, j int);
CREATE TABLE
tdsql=# insert into src_table values (1,2);
INSERT 0 1
tdsql=# select * from update_table;
i | j
---+---
1 | 1
(1 row)
tdsql=# update update_table set j=src_table.j from src_table where update_table.i=src_table.i;
UPDATE 1
tdsql=# select * from update_table;
i | j
---+---
1 | 2
(1 row)
5、 update返回更新的数据
通过returning返回更新结果,可以减少与数据库的交互次数。示例:
tdsql=# update update_table set j=3 returning *;
i | j
---+---
1 | 3
(1 row)
UPDATE 1