返回介绍

I. 教程

II. SQL 语言

III. 服务器管理

IV. 客户端接口

V. 服务器端编程

VI. 参考手册

VII. 内部

VIII. 附录

UPDATE

发布于 2019-09-30 03:11:48 字数 5059 浏览 925 评论 0 收藏 0

名称

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文