PostgreSQL 8.2.3 中文文档
后退快退快进前进

UPDATE

名称

UPDATE -- 更新一个表中的行

语法

UPDATE [ ONLY ] table [ [ AS ] alias ]
    SET { column = { expression | DEFAULT } |
          ( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]
    [ FROM fromlist ]
    [ WHERE condition ]
    [ RETURNING * | output_expression [ AS output_name ] [, ...] ]

描述

UPDATE 改变满足条件的所有行中指定的字段值。只在 SET 子句中出现需要修改的行,没有出现的其他字段保持它们原来的数值。

缺省时,UPDATE 将更新所声明的表和所有子表的记录。如果你希望只更新所声明的表,应该使用 ONLY 子句。

使用同一数据库里其它表的信息来更新一个表有两种方法:使用子查询,或者在 FROM 子句里声明另外一个表。哪个方法更好取决于具体的环境。

可选的 RETURNING 子句将导致 UPDATE 基于每个被更新的行计算返回值。任何 FROM 中使用的字段都可以用于计算。计算的时候使用刚刚被更新过的字段新值。RETURNING 列表的语法与 SELECT 的输出列表相同。

要修改表,你必须对它有 UPDATE 权限,同样对 expressionscondition 条件里提到的任何表也要有 SELECT 权限。

参数

table

现存表的名称(可以有模式修饰)

alias

目标表的别名。如果指定了别名,那么它将完全遮盖表的本名。例如,给定 UPDATE foo AS f 之后,剩余的 UPDATE 语句必须用 f 而不是 foo 引用这个表。

column

table 中的字段名。必要时,字段名可以用子域名或者数组下标修饰。不要在指定字段名的时候加上表名字。比如 UPDATE tab SET tab.col = 1 就是错误的。

expression

给字段赋值的有效值或表达式。表达式可以使用这个或其它字段更新前的旧值。

DEFAULT

把字段设置为它的缺省值,如果没有缺省表达式,那么就是 NULL

fromlist

一个表表达式的列表,允许来自其它表中的字段出现在 WHERE 条件里。这个类似于可以在一个 SELECT 语句的 FROM 子句里声明表列表。请注意目标表绝对不能出现在 fromlist 里,除非你是在使用一个自连接(此时它必须以 fromlist 的别名出现)。

condition

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

output_expression

在所有需要更新的行都被更新之后,UPDATE 命令用于计算返回值的表达式。这个表达式可以使用任何 table 以及 FROM 中列出的表的字段。写上 * 表示返回所有字段。

output_name

字段的返回名称

输出

成功完成后,UPDATE 返回形如

UPDATE count

的命令标签。count 是更新的行数。如果为 0 则表示没有符合 condition 的行(这个不认为是错误)。

如果 UPDATE 包含 RETURNING 子句,那么返回的结果将类似于包含 RETURNING 字段和表达式列表的 SELECT 语句,只不过返回结果是基于被更新的行而已。

注意

在出现 FROM 子句的时候,实际上发生的事情是目标表和 fromlist 里提到的表连接在一起,并且每个连接输出行都代表一个目标表的更新操作。在使用 FROM 的时候,你应该保证连接为每个需要修改的行最多生成一个输出行。换句话说,一个目标行不应该和超过一行来自其它表的数据行连接。如果它连接了多于一个行,那么连接行里面将会只有一行用于更新目标行,但是究竟使用哪行是很难预期的事情。

因为这个不确定性,只再子查询里面引用其它表是安全的,尽管通常更难读并且比使用连接也更慢些。

例子

把表 films 里的字段 kind 里的词 DramaDramatic 代替:

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 公司客户的销售员的销售计数,使用 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;

兼容性

这条命令遵循 SQL 标准。只是 FROMRETURNING 子句是 PostgreSQL 扩展。

标准的字段列表语法允许从行值表达式指定字段列表,比如一个子查询:

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 的方式。移植使用这类扩展的应用时要注意。


后退首页前进
UNLISTEN上一级VACUUM