VastbaseE100

基于开源技术的HTAP数据库管理系统。性能优异,稳定可靠,提供诸多专属领域特性。

Menu

UPDATE

UPDATE - 更新表的行

语法格式

[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    SET { column_name = { expression | DEFAULT } |
          ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
          ( column_name [, ...] ) = ( sub-SELECT )
        } [, ...]
    [ FROM from_list ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

说明

UPDATE 更改满足条件的所有行中指定列的值。 SET子句中只需要提到要修改的列;未显式修改的列保留其先前的值。

有两种方法可以使用数据库中其他表中包含的信息来修改表:使用子选择,或在FROM 子句中指定其他表。哪种技术更合适取决于具体情况。

可选的 RETURNING 子句使 UPDATE根据实际更新的每一行计算和返回值。可以计算使用表的列和/或 FROM中提到的其他表的列的任何表达式。使用表的列的新(更新后)值。 RETURNING列表的语法与 SELECT 的输出列表的语法相同。

您必须具有表中的 UPDATE 权限,或者至少在列出要更新的列上具有 UPDATE权限。你必须对于在 expressions 或 condition 中读取其值的任何列,也具有SELECT 权限。

参数说明

  • with_query

    WITH 子句允许您指定可在 UPDATE 查询中按名称引用的一个或多个子查询。

  • table_name

    要更新的表的名称(可选择模式限定)。如果在表名之前指定了 ONLY,则匹配的行仅在指定的表中更新。如果未指定 ONLY,则在从指定表继承的任何表中也会更新匹配的行。 (可选)可以在表名后指定* 以明确指示包含后代表。

  • alias

    目标表的替代名称。提供别名时,它会完全隐藏表的实际名称。例如,给定UPDATE foo AS f , UPDATE 语句的其余部分必须将此表称为 f 而不是 foo 。

  • column_name

    由 table_name指定的表中列的名称。如果需要,可以使用子字段名称或数组下标限定列名称。不要在目标列的规范中包含表的名称- 例如, UPDATE table_name SET table_name.col = 1 无效。

  • expression

    要分配给列的表达式。表达式可以使用表中此列和其他列的旧值。

  • DEFAULT

    将列设置为其默认值(如果没有为其分配特定的默认表达式,则为NULL)。

  • sub-SELECT

    一个 SELECT子查询,它生成与其前面的括号列列表中列出的输出列一样多的输出列。子查询在执行时必须产生不超过一行。如果它产生一行,则将其列值分配给目标列;如果它不产生任何行,则为目标列分配NULL值。子查询可以引用正在更新的表的当前行的旧值。

  • from_list

    表表达式列表,允许其他表中的列出现在 WHERE条件和更新表达式中。这类似于可以在 SELECT 语句的 FROM Clause中指定的表列表。请注意,目标表不得出现在 from_list中,除非您打算进行自联接(在这种情况下,它必须在 from_list中显示别名)。

  • condition

    返回类型 boolean 的值的表达式。仅更新此表达式返回 true 的行。

  • cursor_name

    在 WHERE CURRENT OF条件中使用的游标的名称。要更新的行是最近从此游标中获取的行。游标必须是UPDATE 目标表上的非分组查询。请注意, WHERE CURRENT OF不能与布尔条件一起指定。有关使用带有 WHERE CURRENT OF的游标的更多信息,请参见 DECLARE。

  • output_expression

    在每行更新后由 UPDATE 命令计算和返回的表达式。表达式可以使用由table_name 命名的表的任何列名或 FROM 中列出的表。写 * 以返回所有列。

  • output_name

    用于返回列的名称。

输出

成功完成后, UPDATE 命令将返回表单的命令标记

UPDATE count

count 是更新的行数,包括其值未更改的匹配行。请注意,当 BEFORE UPDATE触发器抑制更新时,该数字可能小于与 condition 匹配的行数。如果 count为0,则查询不会更新任何行(这不被视为错误)。

如果 UPDATE 命令包含 RETURNING 子句,则结果将类似于 SELECT语句的结果,该语句包含 RETURNING列表中定义的列和值,通过命令更新的行计算。

注意事项

当存在 FROM 子句时,实质上发生的是目标表连接到 from_list中提到的表,并且连接的每个输出行表示目标表的更新操作。使用 FROM时,应确保连接为每个要修改的行生成最多一个输出行。换句话说,目标行不应该连接到其他表的多个行。如果是,那么只有一个连接行将用于更新目标行,但是将使用哪一个不容易预测。

由于这种不确定性,仅在子选择内引用其他表更安全,但通常比使用连接更难阅读和更慢。

对于分区表,更新行可能会导致它不再满足包含分区的分区约束。在这种情况下,如果分区树中存在其他分区,则该行满足其分区约束,然后将行移动到该分区。如果没有这样的分区,则会发生错误。在幕后,行移动实际上是DELETE 和 INSERT 操作。但是,同一行上的并发 UPDATE 或 DELETE可能会错过此行。目前,行不能从作为外部表的分区移动到某个其他分区,但如果外部数据包装器支持它们,则可以将它们移动到外部表中。

示例

在表 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 = '2003-07-03';

执行相同的操作并返回更新的条目:

UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
  WHERE city = 'San Francisco' AND date = '2003-07-03'
  RETURNING temp_lo, temp_hi, prcp;

使用备用列列表语法执行相同的更新:

UPDATE weather SET (temp_lo, temp_hi, prcp) = (temp_lo+1, temp_lo+15, DEFAULT)
  WHERE city = 'San Francisco' AND date = '2003-07-03';

使用 FROM 子句语法增加管理Acme Corporation帐户的销售人员的销售额:

UPDATE employees SET sales_count = sales_count + 1 FROM accounts
  WHERE accounts.name = 'Acme Corporation'
  AND employees.id = accounts.sales_person;

使用 WHERE 子句中的子选择执行相同的操作:

UPDATE employees SET sales_count = sales_count + 1 WHERE id =
  (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');

更新帐户表中的联系人姓名以匹配当前分配的销售人员:

UPDATE accounts SET (contact_first_name, contact_last_name) =
    (SELECT first_name, last_name FROM salesmen
     WHERE salesmen.id = accounts.sales_id);

使用连接可以实现类似的结果:

UPDATE accounts SET contact_first_name = first_name,
                    contact_last_name = last_name
  FROM salesmen WHERE salesmen.id = accounts.sales_id;

但是,如果 salesmen ,第二个查询可能会产生意外结果。 id不是唯一键,而如果存在多个 id匹配,则保证第一个查询引发错误。此外,如果特定 accounts 没有匹配项。sales_id条目,第一个查询将相应的名称字段设置为NULL,而第二个查询根本不会更新该行。

更新摘要表中的统计信息以匹配当前数据:

UPDATE summary s SET (sum_x, sum_y, avg_x, avg_y) =
    (SELECT sum(x), sum(y), avg(x), avg(y) FROM data d
     WHERE d.group_id = s.group_id);

尝试插入新库存项目以及库存数量。如果该项目已存在,则更新现有项目的库存计数。要在不使整个事务失败的情况下执行此操作,请使用保存点:

BEGIN;
-- 其他操作
SAVEPOINT sp1;
INSERT INTO wines VALUES('Chateau Lafite 2003', '24');
-- 假定上述语句由于未被唯一键失败,
-- 那么现在我们发出这些命令:
ROLLBACK TO sp1;
UPDATE wines SET stock = stock + 24 WHERE winename = 'Chateau Lafite 2003';
-- 继续其他操作,并且最终
COMMIT;

更改光标 c_films 当前所在行的表 films 的 kind 列:

UPDATE films SET kind = 'Dramatic' WHERE CURRENT OF c_films;UPDATE films SET kind = 'Dramatic' WHERE CURRENT OF c_films;

兼容性

此命令符合SQL标准,但 FROM 和 RETURNING 子句是Vastbase E100扩展,因为能够将 WITH 与 UPDATE 一起使用。

其他一些数据库系统提供 FROM 选项,其中目标表应该在 FROM 中再次列出。这不是Vastbase E100如何解释 FROM。移植使用此扩展的应用程序时要小心。

根据标准,目标列名称的带括号的子列表的源值可以是任何行值表达式,从而产生正确的列数。Vastbase E100只允许源值为 row constructor或子 SELECT。单个列的更新值可以在行构造函数的情况下指定为 DEFAULT ,但不能在子SELECT 中指定。