选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0
历史版本PostgreSQL 9.1 已于 2016 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

UPDATE

UPDATE — update rows of a table

大纲

[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [ ONLY ] table [ * ] [ [ AS ] alias ]
    SET { column = { expression | DEFAULT } |
          ( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]
    [ FROM from_list ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

描述

UPDATE会更改所有满足条件的行中指定列 的值。只需在SET子句中提及需要修改的列; 未被显式修改的列会保留其原有值。

有两种方法可以利用数据库中其他表所包含的信息来修改一个表:使用子选择, 或者在FROM子句中指定附加表。哪种技术更合适取决 于具体情况。

可选的RETURNING子句使UPDATE 基于每个实际更新的行计算并返回一个或多个值。可以计算任何使用该表列和/或 FROM中提到的其他表列的表达式。默认使用该 表列的新值(更新后值),但也可以请求旧值(更新前值)。 RETURNING列表的语法与SELECT 的输出列表相同。

必须拥有该表上的UPDATE权限,或者至少拥有所列待更新列的该权限。还必须拥有SELECT权限,覆盖在expressionscondition中读取其值的所有列。

参数

with_query

WITH子句允许你指定一个或多个子查询,这些子查 询可在UPDATE查询中按名称引用。详见 第 7.8 节SELECT

table

要更新的表名(可以是模式限定的)。如果在表名前指定了 ONLY,只会更新所提及表中的匹配行。如果未指定 ONLY,还会更新继承自该表的任何表中的匹配行。 可选地,可以在表名后指定*,以显式指示包含后代 表。

alias

目标表的替代名称。提供别名时,它会完全隐藏该表的实际名称。 例如,给定UPDATE foo AS fUPDATE语句的其余部分必须将该表称为 f,而不是foo

column

table_name命名 的表中的列名。如有需要,列名可以使用子字段名或数组下标 进行限定。指定目标列时不要包含表名 — 例如, UPDATE tab SET tab.col = 1是无 效的。

expression

要赋给该列的表达式。该表达式可以使用该表中这一列和其他列的 旧值。

DEFAULT

把该列设置为其默认值(如果没有为它指定特定的默认表达式,则该值为 NULL)。

from_list

一个表表达式列表,允许其他表的列出现在WHERE条件以及更新表达式中。这类似于SELECT语句的FROM Clause中可以指定的表列表。注意,除非打算进行自连接(此时它必须在from_list中带有别名出现),否则目标表不能出现在from_list中。

condition

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

cursor_name

要在WHERE CURRENT OF条件中使用的游标名。要被更新的行是最近一次从该游标中取出的那一行。该游标必须是针对UPDATE目标表的非分组查询。注意,WHERE CURRENT OF不能与布尔条件同时指定。参见DECLARE,了解将游标用于WHERE CURRENT OF的更多信息。

output_expression

在每一行被更新后,由UPDATE命令计算并返回的 表达式。该表达式可以使用由table_name 命名的表或FROM中列出的表中的任何列名。写成 *可返回所有列。

output_name

用于返回列的名称。

输出

成功完成后,UPDATE 命令返回如下形式的命令标签:

UPDATE count

The count is the number of rows updated. If count is 0, no rows matched the condition (this is not considered an error).

如果UPDATE命令包含RETURNING 子句,其结果将类似于一个SELECT语句,其中包含 RETURNING列表中定义的列和值,并在该命令更新的 行上进行计算。

注解

当存在FROM子句时,本质上会将目标表与 from_list中提到的表连接起来,而连接 的每一条输出行都代表对目标表的一次更新操作。使用 FROM时,应确保对每一个要修改的目标行,连接至多 生成一条输出行。换言之,一条目标行不应与其他表中的多于一行成功 连接。如果发生这种情况,则只会使用其中某一条连接行来更新目标行, 但具体使用哪一条并不容易预测。

因为存在这种不确定性,所以仅在子选择中引用其他表会更安全,尽管 这种写法通常比使用连接更难阅读、也更慢。

示例

把表filmskind 列中的单词Drama改为Dramatic

UPDATE films SET kind = 'Dramatic' WHERE kind = 'Drama';

在表weather的一行中调整温度项,并将降水量 重置为其默认值:

UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
  WHERE city = 'San Francisco' AND date = '2003-07-03';

执行同样的操作,并返回更新后的各项:

UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
  WHERE city = 'San Francisco' AND date = '2003-07-03'
  RETURNING temp_lo, temp_hi, prcp;

使用另一种列列表语法完成同样的更新:

UPDATE weather SET (temp_lo, temp_hi, prcp) = (temp_lo+1, temp_lo+15, DEFAULT)
  WHERE city = 'San Francisco' AND date = '2003-07-03';

将负责 Acme Corporation 账户的销售人员的销量计数加一,使用 FROM 子句语法:

UPDATE employees SET sales_count = sales_count + 1 FROM accounts
  WHERE accounts.name = 'Acme Corporation'
  AND employees.id = accounts.sales_person;

执行同样的操作,在 WHERE 子句中使用子选择:

UPDATE employees SET sales_count = sales_count + 1 WHERE id =
  (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');

尝试插入一个新库存项及其库存量。如果该项已存在,则改为更新现有项的库存量。要在不致使整个事务失败的情况下做到这一点,请使用保存点:

BEGIN;
-- 其他操作
SAVEPOINT sp1;
INSERT INTO wines VALUES('Chateau Lafite 2003', '24');
-- 假设上面的语句因唯一键冲突而失败,
-- 那么现在发出这些命令:
ROLLBACK TO sp1;
UPDATE wines SET stock = stock + 24 WHERE winename = 'Chateau Lafite 2003';
-- 继续执行其他操作,最后
COMMIT;

更改 kind 列,该列位于表 films 中,所更改的行是游标 c_films 当前定位的行:

UPDATE films SET kind = 'Dramatic' WHERE CURRENT OF c_films;

兼容性

这个命令符合SQL标准,不过 FROMRETURNING子句是 PostgreSQL扩展,把WITHUPDATE一起使用的能力也是扩展。

按照标准,列列表语法应允许用一个单一的行值表达式(例如子查询)为一组列赋值:

UPDATE accounts SET (contact_last_name, contact_first_name) =
    (SELECT last_name, first_name FROM salesmen
     WHERE salesmen.id = accounts.sales_id);

这一点目前尚未实现—来源必须是独立表达式的列表。

某些其他数据库系统提供一种 FROM 选项,其中目标表被认为要在 FROM 中再次列出。PostgreSQL 不是这样解释 FROM 的。移植使用这一扩展的应用时要小心。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。