UPDATE
UPDATE ステートメントを使用することにより、データベース内の列の値を変更することができます。
構文
UPDATE <テーブル名 | ビュー名> [エイリアス名]
SET 列名 = <NULL | DEFAULT | 式 | サブクエリ式>[, 列名 = ...]
[FROM テーブル参照[, テーブル参照]...
[WHERE 検索条件]
テーブル名 ::= ユーザー定義名
ビュー名 ::= ユーザー定義名
テーブル参照 ::= {OJ 外部結合の定義}
| [
データベース名.]
テーブル名 [[
AS]
エイリアス名]
| [
データベース名.]
ビュー名 [[
AS]
エイリアス名]
| 結合定義
| (結合定義)
| (
テーブルサブクエリ) [
AS]
エイリアス名 [(
列名[,
列名]...)]
外部結合の定義 ::= テーブル参照 外部結合タイプ JOIN テーブル参照 ON 検索条件
外部結合タイプ ::= LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER]
検索条件 ::= 検索条件 AND 検索条件
| 検索条件 OR 検索条件
| NOT 検索条件
| (検索条件)
| 述部
データベース名 ::= ユーザー定義名
ビュー名 ::= ユーザー定義名
結合定義 ::= テーブル参照 [結合タイプ] JOIN テーブル参照 ON 検索条件
| テーブル参照 CROSS JOIN テーブル参照
| 外部結合の定義
結合タイプ ::= INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER]
テーブル サブクエリ ::=
クエリ スペック [[
UNION [
ALL]
クエリ スペック]...]
サブクエリ式 ::= (クエリ スペック)
備考
UPDATE ステートメントは、DELETE および INSERT と同様にアトミックな方法で動作します。つまり、複数の行の更新に失敗した場合、同じステートメントによって実行された前の行の更新がすべてロール バックされます。
UPDATE ステートメントの SET 句にはサブクエリを指定できます。この機能を使用すると、テーブル内の情報を、別のテーブル内のデータまたは同じテーブル内の別の部分を基に更新することができます。
キーワード DEFAULT を使用すると、その値を、指定の列に定義されているデフォルト値に設定することができます。デフォルト値が定義されていないとき、その列がヌル値を許可する場合はヌルを用し、ヌル値を許可しない場合はエラーを返します。デフォルト値と、真のヌルおよび古いリリースのレガシー ヌルの詳細については、
SET TRUENULLCREATE を参照してください。
UPDATE ステートメントは一度に 1 つのテーブルしか更新できません。UPDATE は、SET 句内のサブクエリを使ってほかのテーブルと関連付けることができます。これは、更新するテーブルの内容の一部に依存する相関サブクエリか、または別のテーブルにのみ依存する非相関サブクエリにすることができます。
たとえば、次は相関サブクエリです。
UPDATE t1 SET t1.c2 = (SELECT t2.c2 FROM t2 WHERE t2.c1 = t1.c1)
非相関サブクエリと比較してみましょう。
UPDATE t1 SET t1.c2 = (SELECT SUM(t2.c2) FROM t2 WHERE t2.c1 = 10)
純粋な SELECT ステートメントとサブクエリは同じロジックを使って処理されるため、サブクエリを有効な SELECT ステートメントで構成することができます。サブクエリには特別な規則はありません。
UPDATE 内の SELECT が行を返さない場合、UPDATE はヌルを挿入します。指定した列がヌル値を許可しない場合、UPDATE は失敗します。また、SELECT が複数行を返した場合、UPDATE は失敗します。
UPDATE ステートメントは、ステートメント内でのテーブル結合の使用を許可しません。その代わりに、上の例で示したように SET 句で相関サブクエリを使用します。
真のヌルとレガシー ヌルの詳細については、
SET TRUENULLCREATE を参照してください。
リテラル文字列の最大長より長いデータの更新
Zen でサポートされるリテラル文字列の最大長は 15,000 バイトです。これよりも長いデータを処理するには、直接の SQL ステートメントを使用し、更新を複数の呼び出しに分割します。次のようなステートメントで開始します。
UPDATE table1 SET longfield = '15000 バイトのテキスト' WHERE 制限
次に、それ以上のデータを追加する次のステートメントを発行します。
UPDATE table1 SET longfield = notefield + '15000 バイトを超えるテキスト' WHERE 制限
FROM 句
オプションの FROM 句と、更新されるテーブル(「更新テーブル」と呼びます)への参照に関して混乱が生じる可能性があります。FROM 句に更新テーブルが現れる場合、その出現のうちの 1 つは更新されるテーブルと同じインスタンスになります。
たとえば、ステートメント UPDATE t1 SET c1 = 1 FROM t1, t2 WHERE t1.c2 = t2.c2 の場合、UPDATE の直後の t1 と FROM の後の t1 は、テーブル t1 の同じインスタンスです。したがって、このステートメントは UPDATE t1 SET c1 = 1 FROM t2 WHERE t1.c2 = t2.c2 と同じことになります。
FROM 句に更新テーブルが複数回現れる場合、その出現のうちの 1 つは更新テーブルと同じインスタンスであると識別される必要があります。FROM 句の参照のうち、更新テーブルと同じインスタンスであると見なされるのは、エイリアスが指定されていない参照です。
したがって、ステートメント UPDATE t1 SET t1.c1 = 1 FROM t1 a, t1 b WHERE a.c2 = b.c2 の場合、FROM 句の t1 のインスタンスはどちらもエイリアスを持っているため、これは正しくありません。次であれば有効です。UPDATE t1 SET t1.c1 = 1 FROM t1, t1 b WHERE t1.c2 = b.c2
FROM 句には次の条件が適用されます。
•UPDATE ステートメントにオプションの FROM 句を含める場合、FROM 句の前にあるテーブル参照にエイリアスを指定することはできません。たとえば、UPDATE t1 a SET a.c1 = 1 FROM t2 WHERE a.c2 = t2.c2 とすると、次のエラーが返されます。
SQL_ERROR (-1)
SQLSTATE "37000"
"オプションの FROM を伴う UPDATE/DELETE ステートメントでは、テーブル エイリアスは使用できません。"
ステートメントの有効なバージョンは、UPDATE t1 SET t1.c1 = 1 FROM t2 WHERE t1.c2 = t2.c2 または UPDATE t1 SET t1.c1 = 1 FROM t1 a, t2 WHERE a.c2 = t2.c2 です。
•FROM 句に更新テーブルへの参照を 2 つ以上含める場合、それらの参照のうちの 1 つにだけエイリアスを指定できます。たとえば、UPDATE t1 SET t1.c1 = 1 FROM t1 a, t1 b WHERE a.c2 = b.c2 とすると、次のエラーが返されます。
SQL_ERROR (-1)
SQLSTATE "37000"
"テーブル t1 があいまいです。"
誤りのあるステートメントでは、エイリアスを "a" とするテーブル t1 が更新テーブルと同じインスタンスであると仮定しています。正しいステートメントは、UPDATE t1 SET t1.c1 = 1 FROM t1, t1 b WHERE t1.c2 = b.c2 です。
•UPDATE ステートメントにおける FROM 句はセッション レベルでのみサポートされます。UPDATE ステートメントがストアド プロシージャ内で発生する場合は、FROM 句はサポートされません。
例
次の例では、Faculty テーブルの ID 103657107 に給与として 95000 を設定し、レコードを更新します。
UPDATE Faculty SET salary = 95000.00 WHERE ID = 103657107
============
次の例では、DEFAULT キーワードの使い方を示します。
UPDATE t1 SET c2 = DEFAULT WHERE c2 = 'bcd'
UPDATE t1 SET c1 = DEFAULT, c2 = DEFAULT
============
次の例では、Course テーブルの ECO 305 の履修単位時間を 4 に変更します。
UPDATE Course SET Credit_Hours = 4 WHERE Name = 'ECO 305'
============
次の例は、Person テーブル中のある人物の住所を変更します。
UPDATE Person p
SET p.Street = '123 Lamar',
p.zip = '78758',
p.phone = 5123334444
WHERE p.ID = 131542520
============
サブクエリ例 A
2 つのテーブルが作成され、行が挿入されます。最初のテーブル t5 は、列 c1 に値 2 を持つ各行が、2 番目のテーブル t6 の列の値で更新されます。テーブル t6 には列 c2 に値 3 を含む行が 2 行以上あるために、サブクエリから複数行が返されることから、最初の UPDATE は失敗します。たとえ結果値がどちらの場合も同じになるとしても、このような結果になります。2 番目の UPDATE で示されるように、サブクエリ内で DISTINCT キーワードを使用すると、重複する結果が取り除かれ、ステートメントは成功します。
CREATE TABLE t5 (c1 INT, c2 INT)
CREATE TABLE t6 (c1 INT, c2 INT)
INSERT INTO t5(c1, c2) VALUES (1,3)
INSERT INTO t5(c1, c2) VALUES (2,4)
INSERT INTO t6(c1, c2) VALUES (2,3)
INSERT INTO t6(c1, c2) VALUES (1,2)
INSERT INTO t6(c1, c2) VALUES (3,3)
SELECT * FROM t5
結果:
c1 c2
---------- -----
1 3
2 4
UPDATE t5 SET t5.c1=(SELECT c2 FROM t6 WHERE c2=3) WHERE t5.c1=2 — 注意:クエリは失敗します
UPDATE t5 SET t5.c1=(SELECT DISTINCT c2 FROM t6 WHERE c2=3) WHERE t5.c1=2 — 注意:クエリは成功します
SELECT * FROM t5
結果:
c1 c2
---------- -----
1 3
3 4
============
サブクエリ例 B
2 つのテーブルが作成され、有効な構文のさまざまな例が示されます。サブクエリが複数行を返すことにより UPDATE が失敗する事例に注目してください。また、サブクエリが行を返さない場合に(そこでヌル値が許可される場合)、ヌルが挿入されて UPDATE は成功する点にも注目してください。
CREATE TABLE t1 (c1 INT, c2 INT)
CREATE TABLE t2 (c1 INT, c2 INT)
INSERT INTO t1 VALUES (1, 0)
INSERT INTO t1 VALUES (2, 0)
INSERT INTO t1 VALUES (3, 0)
INSERT INTO t2 VALUES (1, 100)
INSERT INTO t2 VALUES (2, 200)
UPDATE t1 SET t1.c2 = (SELECT SUM(t2.c2) FROM t2)
UPDATE t1 SET t1.c2 = 0
UPDATE t1 SET t1.c2 = (SELECT t2.c2 FROM t2 WHERE t2.c1 = t1.c1)
UPDATE t1 SET t1.c2 = @@IDENTITY
UPDATE t1 SET t1.c2 = @@ROWCOUNT
UPDATE t1 SET t1.c2 = (SELECT @@IDENTITY)
UPDATE t1 SET t1.c2 = (SELECT @@ROWCOUNT)
UPDATE t1 SET t1.c2 = (SELECT t2.c2 FROM t2) — 更新は失敗します
INSERT INTO t2 VALUES (1, 150)
INSERT INTO t2 VALUES (2, 250)
UPDATE t1 SET t1.c2 = (SELECT t2.c2 FROM t2 WHERE t2.c1 = t1.c1) — 更新は失敗します
UPDATE t1 SET t1.c2 = (SELECT t2.c2 FROM t2 WHERE t2.c1 = 5) — 更新は成功し、t1.c2 の全行にヌルが挿入されます
UPDATE t1 SET t1.c2 = (SELECT SUM(t2.c2) FROM t2 WHERE t2.c1 = t1.c1)
============
次の例では、テーブル t1 と t2 を作成し、それらにデータを設定します。UPDATE ステートメントで FROM 句を使用して、新しい値を取得するための別のテーブルを指定します。
DROP table t1
CREATE table t1 (c1 integer, c2 integer)
INSERT INTO t1 VALUES (0, 10)
INSERT INTO t1 VALUES (0, 10)
INSERT INTO t1 VALUES (2, 20)
INSERT INTO t1 VALUES (2, 20)
DROP table t2
CREATE table t2 (c1 integer, c2 integer)
INSERT INTO t2 VALUES (2, 20)
INSERT INTO t2 VALUES (2, 20)
INSERT INTO t2 VALUES (3, 30)
INSERT INTO t2 VALUES (3, 30)
UPDATE t1 SET t1.c1 = t2.c1 FROM t2 WHERE t1.c2 = t2.c2
SELECT * FROM t1
関連項目