<PostgreSQL Conference 2014> 2014年12月5日(金) AP品川
今回は5トラック、全28セッション。PostgreSQLのすべてをこの1日で。詳しくは上記をクリック。
他のバージョンの文書9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

UPDATE

名前

UPDATE -- テーブルの行を更新する

概要

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

説明

UPDATEは、条件を満たす全ての行の指定した列の値を変更します。 SET句には、変更する列のみを指定する必要があります。 SET句にて明示的に指定されなかった列の値は変更されません。

データベース内の他のテーブルの情報を使用してテーブルを変更するには、2つの方法があります。 1つは副問い合わせを使用する方法、もう1つはFROM句で追加するテーブルを指定する方法です。 どちらの方法が適切であるかは状況次第です。

省略可能なRETURNING句により、UPDATEは実際に更新された各行に基づいて計算された値を返すようになります。 そのテーブルの列、FROMで指定された他のテーブルの列、あるいは、その両方を使用した式を計算することができます。 テーブル列の新しい(更新された後の)値が使用されます。 RETURNINGリストの構文はSELECTの出力リストと同一です。

更新を行うためには、そのテーブルまたは少なくとも対象の列上にUPDATE権限を持たなければなりません。 またexpressionsconditionで読み込むテーブルに対するSELECT権限も必要になります。

パラメータ

with_query

WITH句によりUPDATE問い合わせ内で名前で参照可能な1つ以上の副問い合わせを指定することができます。 項7.8SELECTを参照してください。

table_name

更新対象のテーブルの名前です(スキーマ修飾名でも可)。 テーブルの前にONLYを指定すると、指名されたテーブルのみで一致する行が更新されます。 ONLYを指定しないと、指名したテーブルから継承されたすべてのテーブルも一致する行が同時に更新されます。 省略することもできますが、テーブル名の後に*を指定して、明示的に子テーブルが含まれることを示すことができます。

alias

対象テーブルの代替名です。 別名が指定されると、テーブルの実際の名前は完全に隠蔽されます。 たとえば、UPDATE foo AS fでは、UPDATE文の残りの部分ではfooではなくfとしてこのテーブルを参照しなければなりません。

column_name

table_nameで指名されたテーブル内の列名です。 必要に応じて、列名を副フィールド名や配列の指示子で修飾することも可能です。 対象列の指定にはテーブル名を含めないでください。 たとえば、UPDATE tab SET tab.col = 1は無効です。

expression

列に代入する式です。 この式では、テーブル内の対象列やその他の列の変更前の値を使用することができます。

DEFAULT

列にデフォルト値を設定します (デフォルト式が割り当てられていない場合はNULLになります)。

from_list

WHERE条件や更新用の式において、他のテーブルの列を指定するために使用するテーブル式の集合です。 これはSELECT文のFROMで指定するテーブルのリストに似ています。 自己結合を行う場合を除き、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の場合はconditionに一致する行がなかったことを意味します (これはエラーとはみなされません)。

UPDATEコマンドがRETURNING句を持つ場合、その結果は、RETURNINGリストで定義した列と値を持ち、そのコマンドで更新された行全体に対して計算を行うSELECT文の結果と似たものになるでしょう。

注釈

FROM句が存在する場合、基本的に、対象テーブルとfrom_listで指定されたテーブルが結合され、この結合の出力行が対象テーブルの更新操作の結果となります。 FROM句を使用する場合、更新対象テーブルの1行に対して、結合結果が複数行にならないように注意してください。 言い換えると、対象テーブルの個々の行は、他テーブルの複数の行と結合すべきではありません。 結合結果が複数行になった場合、対象行の更新には結合結果のいずれか1行のみが使用されますが、どの行が使用されるかは簡単には予測できません。

このような問題があるため、他テーブルの参照は副問い合わせ内のみに留めておいた方がより安全です(ただし、結合よりも可読性や実行速度は低下します)。

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句構文を使用して、アクメ社を顧客とするセールスマンのセールスカウントを1増加させます。

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');

新しい商品とその在庫数を挿入します。 既にその商品が存在している場合は、代わりに既存商品の在庫数を更新します。 トランザクション全体が失敗することがないようにこの操作を行うには、セーブポイントを使用してください。

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;

filmsテーブルにおいて、c_filmsカーソルが現在位置している行のkind列を変更します。

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

互換性

このコマンドは標準SQLに準拠しています。 ただしFROM句およびRETURNING句はPostgreSQLの拡張です。 UPDATEWITHが使用可能であることも同様に拡張です。

標準に従うと、列リスト構文は、副選択のような単一の行値式から代入される列のリストを許可しなければなりません。

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

これは現時点ではサポートされていません。ソースは独立した式でなければなりません。

他のデータベースシステムには、FROMオプション内で、対象テーブルが再度指定されることを前提として動作するものもあります。 これはPostgreSQLにおけるFROMの解釈方法とは異なります。 FROM拡張機能を使用するアプリケーションを移植する時は注意してください。