UPDATE
UPDATE¶
更新表的行。
- 语法
-
``` sql [ 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权限。注意: 默认情况下,SeaboxMPP数据库为堆表的
UPDATE操作获取表的EXCLUSIVE锁。启用全局死锁检测器后,堆表上UPDATE操作的锁定模式为ROW EXCLUSIVE。成功完成后,
UPDATE命令将返回以下格式的命令标记:UPDATE count其中
count是更新的行数。 如果count为0,则没有符合条件的行(这不视为错误)。 - 参数
-
该SQL命令参数说明见下
with_query-
WITH子句允许您指定一个或多个子查询,这些子查询可以在UPDATE查询中按名称进行引用。对于包含WITH子句的UPDATE命令, 该子句只能包含SELECT命令,而WITH子句不能包含数据修改命令(INSERT,UPDATE或DELETE)。查询(SELECT语句)也可能包含WITH子句。在这种情况下,可以在UPDATE查询中引用两组with_query,但是第二组优先,因为它的嵌套更紧密。WITH子句提供在一个更大的SELECT查询中,使用子查询或执行数据修改操作的方式。你可以在INSERT, UPDATE, 或 DELETE 命令中使用WITH子句。
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与布尔条件一起指定。UPDATE...WHERE CURRENT OF语句只能在服务器上执行,例如在交互式ssql会话或脚本中。 语言扩展(例如PL /pgSQL)不支持可更新的游标。 output_expression- 每行更新后,由
UPDATE命令计算并返回表达式。 该表达式可以使用FROM中列出的一个或多个表的任何列名。输入*以返回所有列。 output_name- 用于返回的列的名称。
- 注解
-
在表的SeaboxMPP分布键列上不允许使用
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帐户的销售人员的销售数量(假设两个被连接的表在SeaboxMPP数据库中都基于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子句是SeaboxMPP数据库扩展。根据标准,列列表语法应允许从单个行值表达式(例如子选择)分配列列表:
UPDATE accounts SET (contact_last_name, contact_first_name) = (SELECT last_name, first_name FROM salesmen WHERE salesmen.id = accounts.sales_id);当前尚未实现-源必须是独立表达式的列表。
其他一些数据库系统提供
FROM选项,该目标表应该在FROM中再次列出。 那不是SeaboxMPP数据库解释FROM的方式。移植使用此扩展名的应用程序时请小心。 - 相关SQL命令
DECLARE,DELETE,SELECT,INSERT