UPDATE [ ONLY ] table [ [ AS ] alias ] SET { column = { expression | DEFAULT } | ( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...] [ FROM fromlist ] [ WHERE condition | WHERE CURRENT OF cursor_name ] [ RETURNING * | output_expression [ AS output_name ] [, ...] ]
UPDATEは、条件を満たす全ての行の指定した列の値を変更します。 SET句には、変更する列のみを指定する必要があります。 SET句にて明示的に指定されなかった列の値は変更されません。
デフォルトでは、UPDATEは指定したテーブルとその副テーブルの行を更新します。 指定されたテーブルのみを更新したい場合はONLY句を使用してください。
データベース内の他のテーブルの情報を使用してテーブルを変更するには、2つの方法があります。 1つは副問い合わせを使用する方法、もう1つはFROM句で追加するテーブルを指定する方法です。 どちらの方法が適切であるかは状況次第です。
省略可能なRETURNING句により、UPDATEは実際に更新された各行に基づいて計算された値を返すようになります。 そのテーブルの列、FROMで指定された他のテーブルの列、あるいは、その両方を使用した式を計算することができます。 テーブル列の新しい(更新された後の)値が使用されます。 RETURNINGリストの構文はSELECTの出力リストと同一です。
テーブルを変更するにはUPDATE権限が必要です。 さらに、expressionsやconditionで読み込むテーブルに対するSELECT権限も必要になります。
更新対象のテーブルの名前です(スキーマ修飾名でも可)。
対象テーブルの代替名です。 別名が指定されると、テーブルの実際の名前は完全に隠蔽されます。 たとえば、UPDATE foo AS fでは、UPDATE文の残りの部分ではfooではなくfとしてこのテーブルを参照しなければなりません。
table内の列名です。 必要に応じて、列名を副フィールド名や配列の指示子で修飾することも可能です。 対象列の指定にはテーブル名を含めないでください。 たとえば、UPDATE tab SET tab.col = 1は無効です。
列に代入する式です。 この式では、テーブル内の対象列やその他の列の変更前の値を使用することができます。
列にデフォルト値を設定します (デフォルト式が割り当てられていない場合はNULLになります)。
WHERE条件や更新用の式において、他のテーブルの列を指定するために使用するテーブル式の集合です。 これはSELECT文のFROM句で指定するテーブルのリストに似ています。 自己結合を行う場合を除き、fromlistに更新対象のテーブルを含める必要はありません (自己結合を行う場合は、fromlist内で更新対象のテーブルとその別名を指定しておく必要があります)。
boolean型の値を返す式です。 この式がtrueを返す行のみが更新されます。
WHERE CURRENT OF条件で使用されるカーソルの名前です。 更新対象の行は、そのカーソルからもっとも最近に取り出された行です。 カーソルは、UPDATEの対象テーブルに対する単純な問い合わせ(結合や集約がない)でなければなりません。 WHERE CURRENT OFを論理条件といっしょに指定することはできません。
各行を更新した後に計算され、UPDATEによって返される式です。 この式には、tableまたはFROMで指定したテーブル(複数可)の任意の列名を使用することができます。 すべての列を返す場合は*と記載してください。
返される列で使用される名前です。
正常に処理が終わると、UPDATEコマンドは以下の形式のコマンドタグを返します。
UPDATE count
countは更新された行数を意味します。 countが0の場合はconditionに一致する行がなかったことを意味します (これはエラーとはみなされません)。
UPDATEコマンドがRETURNING句を持つ場合、その結果は、RETURNINGリストで定義した列と値を持ち、そのコマンドで更新された行全体に対して計算を行うSELECT文の結果と似たものになるでしょう。
FROM句が存在する場合、基本的に、対象テーブルとfromlistで指定されたテーブルが結合され、この結合の出力行が対象テーブルの更新操作の結果となります。 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の拡張です。
標準に従うと、列リスト構文は、副選択のような単一の行値式から代入される列のリストを許可しなければなりません。
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拡張機能を使用するアプリケーションを移植する時は注意してください。