UPDATE
更新表的行。
概要
[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [ONLY] table [[AS] alias]
SET { column = { expression | DEFAULT} |
(column [, ...]) = ({ expression | DEFAULT} [, ...])} [, ...]
[FROM fromlist]
[WHERE condition| WHERE CURRENT OF cursor_name ]
描述
UPDATE
更改所有满足条件的行中指定列的值。
只需在SET
子句中提及要修改的列;
未显式修改的列将保留其先前的值。
默认情况下,UPDATE
将更新指定表及其所有子表中的行。
如果只希望更新提到的特定表,则必须使用ONLY
子句。
有两种方法可以使用数据库中其他表中包含的信息来修改表:使用子选择,或在FROM子句中指定其他表。 哪种技术更合适取决于具体情况。
如果指定了WHERE CURRENT OF
子句,则更新的行是从指定游标中最新获取的行。
复制表不支持WHERE CURRENT OF
子句。
您必须在表上或至少在要更新的列上具有UPDATE
特权。
您还必须拥有读取expression或condition中的任何列的SELECT
特权。
Note: 默认情况下,Greenplum数据库为堆表的UPDATE
操作获取表的EXCLUSIVE
锁。
启用全局死锁检测器后,堆表上UPDATE
操作的锁定模式为ROW EXCLUSIVE
。
请参阅全局死锁检测。
输出
成功完成后,UPDATE
命令将返回以下格式的命令标记:
UPDATE count
其中count是更新的行数。 如果count为0,则没有符合条件的行(这不视为错误)。
参数
with_query
WITH
子句允许您指定一个或多个子查询,这些子查询可以在UPDATE
查询中按名称进行引用。
对于包含WITH
子句的UPDATE
命令,
该子句只能包含SELECT
命令,
而WITH
子句不能包含数据修改命令(INSERT
,UPDATE
或DELETE
)。
查询(SELECT
语句)也可能包含WITH
子句。
在这种情况下,可以在UPDATE
查询中引用两组with_query,但是第二组优先,因为它的嵌套更紧密。
更多信息,请参考
WITH查询(公用表表达式)
和
[SELECT](SELECT.html#topic1)
。
ONLY 如果指定,则仅更新指定表中的行。 如果未指定,还将处理从指定表继承的任何表。
table
现有表的名称(可以用schema修饰)。
alias
目标表的替代名称。
提供别名后,它将完全隐藏表的实际名称。
例如,在给定UPDATE foo AS f
的情况下,
UPDATE
语句的其余部分必须将此表称为f
而不是foo
。
column
表中列的名称。 如果需要,可以使用子字段名称或数组下标来限定列名称。 在目标列的规范中不要包含表的名称。
expression
分配给该列的表达式。 该表达式可以使用表中此列和其他列的旧值。
DEFAULT 将列设置为其默认值(如果未分配任何特定的默认表达式,则为NULL)。
fromlist
表表达式的列表,允许其他表中的列出现在WHERE
条件和更新表达式中。
这类似于可以在SELECT
语句的FROM
子句中指定的表的列表。
请注意,除非您打算进行自连接,否则目标表不得出现在fromlist中(在这种情况下,目标表必须带有别名出现在fromlist中)。
condition
该表达式返回boolean类型的值。 仅此表达式返回true的行将被更新。
cursor_name
在WHERE CURRENT OF
条件中使用的游标名称。
要更新的行是从游标最近获取的行。
游标必须是UPDATE
命令目标表上的非分组查询。
有关创建游标的更多信息,请参见[DECLARE](DECLARE.html#topic1)
。
不能与布尔条件一起指定WHERE CURRENT OF
。
注意,不能将WHERE CURRENT OF
与布尔条件一起指定。
UPDATE...WHERE CURRENT OF
语句只能在服务器上执行,例如在交互式psql会话或脚本中。
语言扩展(例如PL / pgSQL)不支持可更新的游标。
有关创建游标的更多信息,请参见[DECLARE](DECLARE.html#topic1)
。
output_expression
每行更新后,由UPDATE
命令计算并返回表达式。
该表达式可以使用FROM
中列出的一个或多个表的任何列名。
输入*
以返回所有列。
output_name
用于返回的列的名称。
注解
在表的Greenplum分布键列上不允许使用SET
。
当存在FROM
子句时,本质上是将目标表连接到from列表中提到的表,
并且连接的每个输出行都代表目标表的更新操作。
使用FROM
时,应确保该连接为要修改的每一行最多产生一个输出行。
换句话说,目标行不应与其他表中的一行连接。
如果是这样,那么将仅使用连接行之一来更新目标行,但是将很难预测将使用哪一行。
由于存在这种不确定性,因此仅在子选择内引用其他表会更安全,尽管与使用连接相比,通常更难阅读,也更慢。
不支持在分区表的特定分区(子表)上直接执行UPDATE
和DELETE
命令。
而是在根分区表(使用CREATE TABLE
命令创建的表)上执行这些命令。
示例
将表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 = '2016-07-03';
使用替代的列列表语法进行相同的更新:
UPDATE weather SET (temp_lo, temp_hi, prcp) = (temp_lo+1,
temp_lo+15, DEFAULT)
WHERE city = 'San Francisco' AND date = '2016-07-03';
使用FROM
子句语法增加管理Acme Corporation帐户的销售人员的销售数量(假设两个被连接的表在Greenplum数据库中都基于id
列分布):
UPDATE employees SET sales_count = sales_count + 1 FROM
accounts
WHERE accounts.name = 'Acme Corporation'
AND employees.id = accounts.id;
使用WHERE
子句中的子选择来执行相同的操作:
UPDATE employees SET sales_count = sales_count + 1 WHERE id =
(SELECT id 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;
兼容性
该命令符合SQL标准,但FROM
子句是Greenplum数据库扩展。
根据标准,列列表语法应允许从单个行值表达式(例如子选择)分配列列表:
UPDATE accounts SET (contact_last_name, contact_first_name) =
(SELECT last_name, first_name FROM salesmen
WHERE salesmen.id = accounts.sales_id);
当前尚未实现-源必须是独立表达式的列表。
其他一些数据库系统提供FROM
选项,该目标表应该在FROM
中再次列出。
那不是Greenplum数据库解释FROM
的方式。
移植使用此扩展名的应用程序时请小心。
另见
[DECLARE](DECLARE.html#topic1)
,
[DELETE](DELETE.html#topic1)
,
[SELECT](SELECT.html#topic1)
,
[INSERT](INSERT.html#topic1)
Parent topic: SQL Command Reference