カテゴリ:

DML コマンド - 一般

UPDATE

ターゲットテーブルの指定された行を新しい値で更新します。

このトピックの内容:

構文

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

必須パラメーター

ターゲットテーブル

更新するテーブルを指定します。

列名 =

テーブル列で更新する新しい値を指定します。

オプションのパラメーター

FROM 追加テーブル

更新する行の選択または新しい値の設定に使用する1つ以上のテーブルを指定します。ターゲットテーブルを繰り返すと、自己結合が行われることに注意してください。

WHERE 条件

更新するターゲットテーブルの行を指定する式。

デフォルト:値なし(ターゲットテーブルのすべての行が更新されます)

使用上の注意

  • JOIN に基づいて別のテーブル( FROM 句内)で行を更新する場合、ターゲット行は FROM 関係の多くの行に対して結合する場合があります。これが発生すると、 ERROR_ON_NONDETERMINISTIC_UPDATE セッションパラメーターが更新の結果を制御します。

    • FALSE (デフォルト値)の場合、エラーは返されず、結合された行の1つがターゲット行の更新に使用されます。ただし、選択された結合行は非決定的です。

    • IF TRUE、複数の行を結合するターゲット行の値の例を含むエラーが返されます。

    パラメーターを設定するには:

    ALTER SESSION SET ERROR_ON_NONDETERMINISTIC_UPDATE=TRUE;
    

2つのテーブルを使用して標準の更新を実行します。

UPDATE t1
  SET t1.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;

非決定的な結果を生成する結合で更新します。

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 |
+------------------------+-------------------------------------+
  • ERROR_ON_NONDETERMINISTIC_UPDATE = FALSEの場合、ステートメントは src の次の行のいずれかの値を使用して、 target の単一の行をランダムに更新します。

    (0, 11)(0, 12)(0,13)

  • ERROR_ON_NONDETERMINISTIC_UPDATE = TRUE の場合、重複した DML 行 [0, 10] を報告するエラーが返されます。

この非決定的な動作とエラーを回避するには、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;

このステートメントにより、 target の単一行が (0, 11)srcv の最小値を持つ行の値)に更新され、結果がエラーになることはありません。