UPDATE

使用新值更新目标表中的指定行。

语法

UPDATE <target_table>
       SET <col_name> = <value> [ , <col_name> = <value> , ... ]
        [ FROM <additional_tables> ]
        [ WHERE <condition> ]
Copy

必填参数

target_table

指定要更新的表。

col_name

指定 target_table 中的列的名称。请勿包含表名称。例如,UPDATE t1 SET t1.col = 1 无效。

value

指定要在 col_name 中设置的新值。

可选参数

FROM additional_tables

指定用于选择要更新的行或设置新值的一个或多个表。请注意,重复目标表会导致自联接。

WHERE condition

表达式,指定目标表中要更新的行。

默认:无值(目标表的所有行都已更新)

使用说明

  • FROM 子句包含表之间(例如 t1t2)的 JOIN 时,t1 中的目标行可以联接(即匹配)表 t2 中的多行。发生这种情况时,目标行称为 多联接行。更新多联接行时,ERROR_ON_NONDETERMINISTIC_UPDATE 会话参数控制更新的结果:

    • 如果为 FALSE (默认值),则不返回任何错误,并且使用其中一个联接行来更新目标行;但是,选定的联接行是不确定的。

    • IF TRUE,则返回错误,包括联接多行的目标行的值示例。

    要设置参数,请执行以下操作:

    ALTER SESSION SET ERROR_ON_NONDETERMINISTIC_UPDATE=TRUE;
    
    Copy

示例

使用两个表执行标准更新:

UPDATE t1
  SET number_column = t1.number_column + t2.number_column, t1.text_column = 'ASDF'
  FROM t2
  WHERE t1.key_column = t2.t1_key and t1.number_column < 10;
Copy

使用产生不确定结果的联接进行更新:

select * from target;

+---+----+
| K |  V |
|---+----|
| 0 | 10 |
+---+----+

Select * from src;

+---+----+
| K |  V |
|---+----|
| 0 | 11 |
| 0 | 12 |
| 0 | 13 |
+---+----+

-- Following statement joins all three rows in src against the single row in target
UPDATE target
  SET v = src.v
  FROM src
  WHERE target.k = src.k;

+------------------------+-------------------------------------+
| number of rows updated | number of multi-joined rows updated |
|------------------------+-------------------------------------|
|                      1 |                                   1 |
+------------------------+-------------------------------------+
Copy

要避免这种不确定行为和错误,请使用 1 对 1 联接:

UPDATE target SET v = b.v
  FROM (SELECT k, MIN(v) v FROM src GROUP BY k) b
  WHERE target.k = b.k;
Copy

该语句导致 target 中的单行更新为 (0, 11)`(来自 :code:`srcv 的最小值所在行的值),并且永远不会导致错误。

语言: 中文