On this page
UPDATE
UPDATE —更新表的行
Synopsis
[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
SET { column_name = { expression | DEFAULT } |
( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
( column_name [, ...] ) = ( sub-SELECT )
} [, ...]
[ FROM from_item [, ...] ]
[ WHERE condition | WHERE CURRENT OF cursor_name ]
[ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
Description
UPDATE
更改所有满足条件的行中指定列的值。 SET
子句中仅需提及要修改的列;未显式修改的列将保留其先前的值。
有两种方法可以使用数据库中其他表中包含的信息来修改表:使用子选择,或在FROM
子句中指定其他表。哪种技术更合适取决于具体情况。
可选的RETURNING
子句使UPDATE
根据实际更新的每一行计算并返回值。可以计算使用表的列和/或FROM
中提到的其他表的列的任何表达式。使用表列的新(更新后)值。 RETURNING
列表的语法与SELECT
的输出列表的语法相同。
您必须在表上或至少在要更新的列上具有UPDATE
特权。您还必须对在* expressions
或 condition
*中读取其值的任何列具有SELECT
特权。
Parameters
with_query
WITH
子句允许您指定一个或多个子查询,这些子查询可以在UPDATE
查询中按名称引用。有关详情,请参见Section 7.8和SELECT。
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_item
- 一个表表达式,允许其他表中的列出现在
WHERE
条件中并更新表达式。它使用与SELECT
语句的FROM Clause相同的语法;例如,可以指定表名的别名。除非打算使用自联接,否则不要将目标表重复为*from_item
(在这种情况下,它必须在from_item
*中以别名出现)。
- 一个表表达式,允许其他表中的列出现在
condition
- 该表达式返回类型为
boolean
的值。仅此表达式返回true
的行将被更新。
- 该表达式返回类型为
cursor_name
- 在
WHERE CURRENT OF
条件中使用的游标名称。要更新的行是从该游标最近获取的行。游标必须是对UPDATE
的目标表的非分组查询。请注意,不能将WHERE CURRENT OF
与布尔条件一起指定。有关将游标与WHERE CURRENT OF
结合使用的更多信息,请参见DECLARE。
- 在
output_expression
- 每行更新后,由
UPDATE
命令计算并返回的表达式。该表达式可以使用*table_name
*命名的表或FROM
中列出的表的任何列名。写入*
以返回所有列。
- 每行更新后,由
output_name
- 用于返回的列的名称。
Outputs
成功完成后,UPDATE
命令将返回以下形式的命令标签:
UPDATE count
count
是已更新的行数,包括其值未更改的匹配行。请注意,当通过BEFORE UPDATE
触发器抑制更新时,该数目可能小于与condition
匹配的行数。如果count
*为 0,则查询没有更新任何行(这不视为错误)。
如果UPDATE
命令包含RETURNING
子句,则结果将类似于SELECT
语句的结果,该语句包含在RETURNING
列表中定义的列和值,并通过该命令更新的行进行计算。
Notes
当存在FROM
子句时,本质上是将目标表连接到* from_item
*列表中提到的表,并且连接的每个输出行都代表目标表的更新操作。使用FROM
时,应确保该联接为要修改的每一行最多产生一个输出行。换句话说,目标行不应与其他表中的行合并。如果是这样,那么将仅使用联接行之一来更新目标行,但是将很难预测将使用哪一行。
由于存在这种不确定性,因此仅在子选择内引用其他表更为安全,尽管与使用联接相比,通常更难阅读且速度较慢。
对于分区表,更新行可能导致其不再满足分区约束。由于没有提供将行移动到适合其分区键的新值的分区的功能,因此在这种情况下将发生错误。直接更新分区时也会发生这种情况。
Examples
在表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';
使用FROM
子句语法,增加 ManagementAcme Corporation 帐户的销售人员的销售数量:
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');
更新 Client 表中的联系人姓名以匹配当前分配的销售员:
UPDATE accounts SET (contact_first_name, contact_last_name) =
(SELECT first_name, last_name FROM salesmen
WHERE salesmen.id = accounts.sales_id);
通过联接可以实现类似的结果:
UPDATE accounts SET contact_first_name = first_name,
contact_last_name = last_name
FROM salesmen WHERE salesmen.id = accounts.sales_id;
但是,如果salesmen
,则第二个查询可能会给出意外结果。 id
不是唯一键,但是如果有多个id
匹配项,则保证第一个查询会引发错误。另外,如果没有匹配特定的accounts
。 sales_id
条目,第一个查询会将相应的名称字段设置为 NULL,而第二个查询则根本不会更新该行。
更新摘要表中的统计信息以匹配当前数据:
UPDATE summary s SET (sum_x, sum_y, avg_x, avg_y) =
(SELECT sum(x), sum(y), avg(x), avg(y) FROM data d
WHERE d.group_id = s.group_id);
尝试插入新的库存商品以及库存数量。如果物料已经存在,请更新现有物料的库存数量。要在不使整个事务失败的情况下执行此操作,请使用保存点:
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;
在光标c_films
当前所在的行中更改表films
的kind
列:
UPDATE films SET kind = 'Dramatic' WHERE CURRENT OF c_films;
Compatibility
该命令符合 SQL 标准,除了FROM
和RETURNING
子句是 PostgreSQL 扩展,以及将WITH
与UPDATE
结合使用的能力。
其他一些数据库系统提供了FROM
选项,其中应该在FROM
内再次列出目标表。 PostgreSQL 不会这样解释FROM
。移植使用此 extensions 的应用程序时请小心。
根据该标准,目标列名称的带括号的子列表的源值可以是产生正确列数的任何行值表达式。 PostgreSQL 仅允许源值是row constructor或子SELECT
。在行构造器的情况下,可以将单个列的更新值指定为DEFAULT
,但不能在子SELECT
内指定。