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特权。 您还必须拥有读取expression或condition中的任何列的SELECT特权。
成功完成后,UPDATE命令将返回以下格式的命令标记:
UPDATE count
其中count是更新的行数。 如果count为0,则没有符合条件的行(这不视为错误)。
参数
- with_query
- WITH子句允许您指定一个或多个子查询,这些子查询可以在UPDATE查询中按名称进行引用。
- 对于包含WITH子句的UPDATE命令, 该子句只能包含SELECT命令, 而WITH子句不能包含数据修改命令(INSERT,UPDATE或DELETE)。
- 查询(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时,应确保该连接为要修改的每一行最多产生一个输出行。 换句话说,目标行不应与其他表中的一行连接。 如果是这样,那么将仅使用连接行之一来更新目标行,但是将很难预测将使用哪一行。
由于存在这种不确定性,因此仅在子选择内引用其他表会更安全,尽管与使用连接相比,通常更难阅读,也更慢。
不支持在分区表的特定分区(子表)上直接执行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的方式。 移植使用此扩展名的应用程序时请小心。