いくつかのビューは更新可能です。つまり、これらのビューを UPDATE
、DELETE
、INSERT
などのステートメントで使用して、ベースとなるテーブルの内容を更新できます。ビューが更新可能であるためには、そのビュー内の行とベースとなるテーブル内の行の間に 1 対 1 の関係が存在する必要があります。また、ビューを更新不可能にするその他の特定の構造構文も存在します。より具体的には、次のいずれかを含む場合、ビューは更新可能ではありません。
集計関数 (
SUM()
、MIN()
、MAX()
、COUNT()
など)DISTINCT
GROUP BY
HAVING
UNION
またはUNION ALL
選択リスト内のサブクエリー
特定の結合 (このセクションで後述する結合に関する追加説明を参照してください)
FROM
句内の更新不可能なビューFROM
句内のテーブルを参照するWHERE
句内のサブクエリーリテラル値だけの参照 (この場合、更新するベースとなるテーブルがありません)
ALGORITHM = TEMPTABLE
の使用 (一時テーブルを使用すると常にビューは更新不可能になります)ベーステーブルのいずれかのカラムに対する複数の参照。
挿入可能性 (INSERT
ステートメントで更新可能であること) については、更新可能なビューがビューカラムに対する次の追加要件も満たしている場合に挿入可能になります。
重複したビューカラム名が存在しないようにする必要があります。
ビューには、デフォルト値を持たない、ベーステーブル内のすべてのカラムが含まれている必要があります。
-
ビューカラムは、派生カラムではなく、単純なカラム参照である必要があります。派生カラムは、単純なカラム参照ではなく、式から派生したカラムです。派生したカラムの例は次のとおりです。
3.14159 col1 + 3 UPPER(col2) col3 / col4 (subquery)
単純なカラム参照と派生カラムが混在しているビューは挿入できませんが、派生カラム以外のカラムだけを更新する場合は、更新可能になります。次のビューを考えてみてください。
CREATE VIEW v AS SELECT col1, 1 AS col2 FROM t;
このビューは、col2
が式から派生しているので挿入できません。ただし、更新で col2
を更新しようとしていない場合は、更新可能になります。次の更新は許可されます。
UPDATE v SET col1 = 0;
次の更新は、派生カラムを更新しようとしているので、許可されません。
UPDATE v SET col2 = 0;
MERGE
アルゴリズムで処理できるとすれば、複数テーブルビューが更新できる可能性があります。これを実現するには、ビューで (外部結合または UNION
ではなく) 内部結合を使用する必要があります。また、ビュー定義内の単一のテーブルだけを更新できるので、SET
句は、ビュー内のいずれかのテーブルのカラムだけを指名する必要があります。UNION ALL
を使用するビューは、実装が一時テーブルを使用して処理するので、理論的に更新可能でも許可されません。
更新可能な複数テーブルビューでは、INSERT
は、単一のテーブルに挿入する場合に機能します。DELETE
はサポートされません。
INSERT DELAYED
は、ビューではサポートされません。
テーブルに AUTO_INCREMENT
カラムが含まれている場合、AUTO_INCREMENT
カラムが含まれていないテーブル上の挿入可能なビューに挿入すると、LAST_INSERT_ID()
の値を変更しません。これは、ビューの一部ではないカラムにデフォルト値を挿入した副作用が現れないようにするためです。
更新可能なビューに対して WITH CHECK OPTION
句を指定すると、select_statement
内の WHERE
句が true である行を除く行への挿入または更新を回避できます。
更新可能なビューに対する WITH CHECK OPTION
句では、そのビューが別のビューとの関連で定義されている場合、LOCAL
および CASCADED
キーワードによってチェックテストのスコープが決定されます。LOCAL
キーワードは、CHECK OPTION
を、定義されているビューのみに制限します。CASCADED
を指定すると、ベースとなるビューに対するチェックも評価されます。どちらのキーワードも指定されていない場合、デフォルトは CASCADED
になります。次のテーブルと一連のビューの定義を考えてみてください。
mysql> CREATE TABLE t1 (a INT);
mysql> CREATE VIEW v1 AS SELECT * FROM t1 WHERE a < 2
-> WITH CHECK OPTION;
mysql> CREATE VIEW v2 AS SELECT * FROM v1 WHERE a > 0
-> WITH LOCAL CHECK OPTION;
mysql> CREATE VIEW v3 AS SELECT * FROM v1 WHERE a > 0
-> WITH CASCADED CHECK OPTION;
ここで、v2
および v3
ビューは、v1
という別のビューの観点で定義されています。v2
には LOCAL
チェックオプションがあるので、挿入は、v2
チェックに対してのみテストされます。v3
には CASCADED
チェックオプションがあるので、挿入はそれ自身のチェックに対してだけでなく、ベースとなるビューのチェックに対してもテストされます。次のステートメントでこれらの違いを示しています。
mysql> INSERT INTO v2 VALUES (2);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO v3 VALUES (2);
ERROR 1369 (HY000): CHECK OPTION failed 'test.v3'
MySQL は、CREATE VIEW
時に、ビューの更新可能性フラグというフラグを設定します。UPDATE
および DELETE
(および同様の操作) がビューで有効な場合、フラグは YES
(true) に設定されます。それ以外の場合、フラグは NO
(false) に設定されます。INFORMATION_SCHEMA.VIEWS
テーブルの IS_UPDATABLE
カラムは、このフラグのステータスを表示します。これは、ビューが更新可能であるかどうかをサーバーが常に把握していることを意味します。ビューが更新可能ではない場合、UPDATE
、DELETE
、INSERT
などのステートメントは無効であり、拒否されます。(このセクションの別の箇所で説明しているように、ビューが更新可能である場合でも、ビューへの挿入はできない場合もあります。)
ビューを更新できるかどうかは、updatable_views_with_limit
システム変数の値に影響されます。セクション5.1.4「サーバーシステム変数」を参照してください。