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