UPDATE

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特权。 您还必须拥有读取expressioncondition中的任何列的SELECT特权。

Note: 默认情况下,Greenplum数据库为堆表的UPDATE操作获取表的EXCLUSIVE锁。 启用全局死锁检测器后,堆表上UPDATE操作的锁定模式为ROW EXCLUSIVE。 请参阅全局死锁检测
输出

成功完成后,UPDATE命令将返回以下格式的命令标记:

UPDATE count

其中count是更新的行数。 如果count为0,则没有符合条件的行(这不视为错误)。

参数

with_query
WITH子句允许您指定一个或多个子查询,这些子查询可以在UPDATE查询中按名称进行引用。
对于包含WITH子句的UPDATE命令, 该子句只能包含SELECT命令, 而WITH子句不能包含数据修改命令(INSERTUPDATEDELETE)。
查询(SELECT语句)也可能包含WITH子句。 在这种情况下,可以在UPDATE查询中引用两组with_query,但是第二组优先,因为它的嵌套更紧密。
更多信息,请参考 WITH查询(公用表表达式)SELECT
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
不能与布尔条件一起指定WHERE CURRENT OF
注意,不能将WHERE CURRENT OF与布尔条件一起指定。 UPDATE...WHERE CURRENT OF语句只能在服务器上执行,例如在交互式psql会话或脚本中。 语言扩展(例如PL / pgSQL)不支持可更新的游标。
有关创建游标的更多信息,请参见DECLARE
output_expression
每行更新后,由UPDATE命令计算并返回表达式。 该表达式可以使用FROM中列出的一个或多个表的任何列名。 输入*以返回所有列。
output_name
用于返回的列的名称。

注解

在表的Greenplum分布键列上不允许使用SET

当存在FROM子句时,本质上是将目标表连接到from列表中提到的表, 并且连接的每个输出行都代表目标表的更新操作。 使用FROM时,应确保该连接为要修改的每一行最多产生一个输出行。 换句话说,目标行不应与其他表中的一行连接。 如果是这样,那么将仅使用连接行之一来更新目标行,但是将很难预测将使用哪一行。

由于存在这种不确定性,因此仅在子选择内引用其他表会更安全,尽管与使用连接相比,通常更难阅读,也更慢。

不支持在分区表的特定分区(子表)上直接执行UPDATEDELETE命令。 而是在根分区表(使用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 , DELETE , SELECT , INSERT