SQL 構文リファレンス : UPDATE
 
このページをシェアする                  
UPDATE
UPDATE ステートメントを使って、データベース内の列の値を変更することができます。
構文
UPDATE <テーブル名 | ビュー名> [エイリアス名]
SET 列名 = <NULL | DEFAULT | | サブクエリ式>[, 列名 = ...]
[FROM テーブル参照[, テーブル参照]...
[WHERE 検索条件]
 
テーブル名 ::= ユーザー定義名
 
ビュー名 ::= ユーザー定義名
 
エイリアス名 ::= ユーザー定義名(エイリアス名は、FROM 句が使用されている場合には使用できません。FROM 句を参照してください。)
 
テーブル参照 ::= {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]
クエリ スペック]...]
 
サブクエリ式 ::= (クエリ スペック)
備考
INSERTUPDATE、および DELETE ステートメントはアトミックな方法で動作します。つまり、複数の行の挿入、更新、または削除に失敗した場合、同じステートメントによって実行された前の行の挿入、更新、または削除がすべてロール バックされます。
UPDATE ステートメントの SET 句にはサブクエリを指定できます。この機能を使用すると、テーブル内の情報を、別のテーブル内の情報または同じテーブル内の別の部分を基に更新することができます。
キーワード DEFAULT を指定すると、指定した列に定義されているデフォルト値を値に設定することができます。デフォルト値が定義されていないとき、Pervasive PSQL は、その列がヌル値を許可する場合はヌルか疑似ヌル値を使用し、ヌル値を許可しない場合はエラーを返します。また、INSERT に記述されている DEFAULT の詳細も参照してください。
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 句で相関サブクエリを使用します。
UPDATE t1 SET t1.c2 = (SELECT t2.c2 FROM t2 WHERE t2.c1 = t1.c1)
Pervasive.SQL 2000 あるいはそれ以前のバージョンで作成されたデータ(レガシー データ)のデータ型はすべて、ヌル値を許可すると報告されます。これは、すべてのデータ型のレガシー列で、擬似ヌル変換を行わないでヌルを更新できるということです。次のデータ型は、デフォルトで擬似ヌルとして扱われます。
Date
Decimal
Money
Numeric
NumericSA
NumericSTS
Timestamp
 
通常、レガシー列を擬似ヌルに変換する場合、列の内容がヌルであるか照会できるように、バイナリ値の 1 つを取り上げてヌル値として使用するため、バイナリ値を 1 つ失います。ただし、上記のデータ型は設計の都合上、通常のデータ範囲に加えて、ヌル用に異なる固有の内部値を持っています。これらのデータ型を使用すると、バイナリ値をヌルに変換する場合に 1 つも値を失わないので、それらをデフォルトで擬似ヌルと判断しても差し支えありません。
残りのデータ型は「レガシー ヌル許容」とみなされます。これは、ヌルを更新できるということです。しかし、値を照会すると、非ヌルのバイナリ同値が返されます。これと同じバイナリ同値を WHERE 句で使用して、特定の値を取得する必要があります。
バイナリ同値は次のとおりです。
Binary 型の場合は 0
string および BLOB 型(レガシー型の LVAR と NOTE)の場合は空文字列
メモ: 単一のリテラル文字列の最大長は 15,000 バイトです。これよりも長いデータを入力する必要がある場合は、Long データを参照すると役に立つヒントがあります。
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"
"[Pervasive][ODBC クライアント インターフェイス][LNA][Pervasive] [ODBC エンジン インターフェイス]オプションの 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" および
"[Pervasive][ODBC クライアント インターフェイス][LNA][Pervasive] [ODBC エンジン インターフェイス]テーブル 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 = 1 FROM t2 WHERE t1.c2 = t2.c2
SELECT * FROM t1
関連項目
ALTER TABLE
CREATE PROCEDURE
CREATE TRIGGER
DEFAULT
GRANT
INSERT