©
This document uses PHP Chinese website manual Release
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子句 中出现需要修改的行,没有出现的其他字段保持它们原来的数值。
缺省时,UPDATE将更新所声明的表和所有子表的记录。如果你希望只更新所声明的表, 应该使用ONLY子句。
使用同一数据库里其它表的信息来更新一个表有两种方法:使用子查询,或者在FROM子句 里声明另外一个表。哪个方法更好取决于具体的环境。
可选的RETURNING子句将导致UPDATE基于每个被更新的行计算返回值。任何 FROM中使用的字段都可以用于计算。计算的时候使用刚刚被更新过的字段新值。 RETURNING列表的语法与SELECT的输出列表相同。
您必须对表有UPDATE权限,或者至少在更新的列上。您必须也在 任何列上都有权限,这些列的值会在expressions或者 condition中读取。
现存表的名称(可以有模式修饰)
目标表的别名。如果指定了别名,那么它将完全遮盖表的本名。例如,给定UPDATE foo AS f之后, 剩余的UPDATE语句必须用f而不是foo引用这个表。
表table中的字段名。必要时,字段名可以用子域名或者数 组下标修饰。不要在指定字段名的时候加上表名字。比如UPDATE tab SET tab.col = 1就是错误的。
分配给列的表达式。表达式可以使用这个或其它字段更新前的旧值。
把字段设置为它的缺省值,如果没有缺省表达式,那么就是 NULL。
一个表表达式的列表,允许来自其它表中的字段出现在WHERE条件里。 这个类似于可以在一个SELECT语句的 FROM子句子句里声明表列表。请注意 目标表绝对不能出现在from_list里,除非你是在使用一个自连接 (此时它必须以from_list的别名出现)。
一个返回boolean结果的表达式。只有这个表达式返回true的行才会被更新。
在WHERE CURRENT OF条件下使用的游标的名称。要更新的行是一个最近从该游标 中抓去的。该游标必须是一个UPDATE目标表中的非分组查询。请注意 WHERE CURRENT OF不能用布尔条件声明。参阅DECLARE 获取更多关于通过WHERE CURRENT OF使用游标的信息。
在所有需要更新的行都被更新之后,UPDATE命令用于计算返回值的表达式。 这个表达式可以使用任何table以及FROM 中列出的表的字段。写上*表示返回所有字段。
字段的返回名称
成功完成后,UPDATE返回形如
UPDATE count
的命令标签。count是更新的行数。如果为 0 则表示没有符合condition的行(这个不认为是错误)。
如果UPDATE包含RETURNING子句,那么返回的结果将类似于包含 RETURNING字段和表达式列表的SELECT语句,只不过返回结果是基于被更新的行而已。
在出现FROM子句的时候,实际上发生的事情是目标表和from_list 里提到的表连接在一起,并且每个连接输出行都代表一个目标表的更新操作。在使用FROM的时候, 你应该保证连接为每个需要修改的行最多生成一个输出行。换句话说,一个目标行不应该和超过一行来自其它 表的数据行连接。如果它连接了多于一个行,那么连接行里面将会只有一行用于更新目标行,但是究竟使用哪 行是很难预期的事情。
因为这个不确定性,只再子查询里面引用其它表是安全的,尽管通常更难读并且比使用连接也更慢些。
把表films里的字段kind里的词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 公司客户的销售员的销售计数,使用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; -- other operations SAVEPOINT sp1; INSERT INTO wines VALUES('Chateau Lafite 2003', '24'); -- Assume the above fails because of a unique key violation, -- so now we issue these commands: ROLLBACK TO sp1; UPDATE wines SET stock = stock + 24 WHERE winename = 'Chateau Lafite 2003'; -- continue with other operations, and eventually COMMIT;
更改表films的kind列,在游标c_films 目前定位的行上:
UPDATE films SET kind = 'Dramatic' WHERE CURRENT OF c_films;
这条命令遵循SQL标准。只是FROM和RETURNING 子句是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的方式。移植使用这类扩展的应用时要注意。