目次へ

9.3. ビューの変更

定義したビューに対してデータを変更することもできます。ビューはデータの入っていない仮想的なテーブルなので、実際にはビューの元になる実テーブルのデータが変更されることになります。また、ビューのデータの変更は実テーブルに定義されている制約を受けます。

データの追加、更新及び削除はテーブルの時と同じように、INSERT 文、UPDATE 文、DELETE 文を用いて実行します。ここでは受注表から商品コードが '101' のものだけを抽出する v_101 を定義します。そして v_101 に対して、受注番号 = '10013'、顧客コード = '002'、受注個数 = 120、納品日 = '20010406' の行を追加します。

-- sample.21-3 --
/* v_101の定義 */

  CREATE VIEW v_101 AS SELECT * FROM 受注表
    WHERE 商品コード = '101' ;
/* v_101の確認 */

  SELECT * FROM v_101 ;

実行結果

 受注番号  顧客コード   商品コード  受注個数   納品日
 ──────── ────────── ────────── ──────── ───────
 10002    002        101        200      20010401
 10003    004        101        150      20010401
 10008    004        101        135      20010403
 10010    001        101        290      20010403
 10012    004        101        175      20010404

実行結果
/* INSERT */

  INSERT INTO v_101
    VALUES('10013', '002', '101', 120, '20010406') ;

/* INSERT 後の確認 */

  SELECT * FROM v_101 ;

実行結果

 受注番号  顧客コード   商品コード  受注個数   納品日
 ──────── ────────── ────────── ──────── ───────
 10002    002        101        200      20010401
 10003    004        101        150      20010401
 10008    004        101        135      20010403
 10010    001        101        290      20010403
 10012    004        101        175      20010404
 10013    002        101        120      20010406

データが追加された後の受注表は sample.21-4 のようになります。

-- sample.21-4 --
/* 受注表 */

  SELECT * FROM 受注表 ;

実行結果

 受注番号  顧客コード   商品コード  受注個数   納品日
 ──────── ────────── ────────── ──────── ───────
 10001    001        102        300      20010401
 10002    002        101        200      20010401
 10003    004        101        150      20010401
 10004    004        102        80       20010402
 10005    002        104        110      20010402
 10006    001        103        250      20010402
 10007    003        102        45       20010402
 10008    004        101        135      20010403
 10009    003        103        65       20010403
 10010    001        101        290      20010403
 10011    003        103        60       20010404
 10012    004        101        175      20010404
 10013    002        101        120      20010406

ビュー v_101 に商品コード '102' のデータを挿入した場合はどうなるでしょうか? ビュー v_101 の定義では商品コード '101' のものを抽出するようになっています。結果は、エラーにはならず挿入できてしまいます。挿入は可能ですが、sample.21-3 の出力結果には、挿入した行は出力されません。これは、INSERT 文により行の挿入は完了し、実テーブルである受注表にデータが書き込まれます。しかし、sample.21-3 で定義したビュー v_101 では商品コードが '101' のもののみを抽出するようになっていますので、挿入した行は出力されないということになります。

本来ビュー v_101 に商品コードが '101' 以外のデータを挿入することに意味はありません。INSERT 文に商品コードが '101' のデータ以外を挿入させないようにするには、sample.21-3 のビュー v_101 の定義のところで WITH CHECK OPTION 句を指定し、明示的に条件 (WHERE 句) に反する行が挿入される場合はエラーメッセージが返されるようにします。

-- sample.21-5 --
/* v_101の定義 WITH CHECK OPTION */

  CREATE v_101 AS SELECT * FROM 受注表
    WHERE 商品コード = '101'
    WITH CHECK OPTION ;

次に、sample.21-6 のように v_102 というビューを定義したときに、受注番号 '10014'、顧客コード '002'、受注個数 '125' という行を挿入することを考えます。

-- sample.21-6 --
/* v_102の定義 WITH CHECK OPTION */

  CREATE v_102 AS
    SELECT 受注番号,顧客コード,受注個数 FROM 受注表
      WHERE 商品コード = '102'
      WITH CHECK OPTION ;

/* 行の挿入 */

  INSERT INTO v_102
    VALUES('10014', '002', 125);

/* 確認 */

  SELECT * FROM v_102 ;

実行結果
 受注番号  顧客コード   受注個数
 ──────── ────────── ────────
 10001    001        300
 10004    004        80
 10007    003        45
 10014    002        125

sample.21-6 の INSERT 文を実行した後の、実テーブルにはどのようなデータが入るでしょうか? ビュー v_102 は受注番号、顧客コード、受注個数しかないため、ビューに行が追加されたとき、顧客コード、納品日には、デフォルト値が与えられていない場合は、NULL が自動的に挿入されることになります。実テーブルでデフォルト値が設定されていれば、デフォルト値が挿入されます。もし、顧客コード、納品日の列制約として NOT NULL が定義されていた場合は、エラーとなり v_102 に行の挿入はできなくなります。すなわち、実テーブルで定義した制約がここにも反映されることになります。この後の、データの更新の際も同様のことが言えます。

ちなみに、実テーブルの確認を sample.21-7 で行っています。出力結果のように、受注番号が '10014' の行の商品コードと納品日は NULL となります。このように、商品コードも NULL となってしまうため、データを挿入する可能性のある場合は、ビューの定義で商品コードも出力列として定義しておいたほうがよいと思われます。

-- sample.21-7 --
/* 実テーブルの確認 */

  SELECT * FROM 受注表
    WHERE 商品コード = '102' ;

実行結果
/* 出力結果 */

 受注番号  顧客コード   商品コード  受注個数   納品日
 ──────── ────────── ────────── ──────── ──────
 10001    001        102        300      20010401
 10004    004        102        80       20010402
 10007    003        102        45       20010402
 10014    002        NULL       125      NULL

データの更新は UPDATE 文を用います。sample.21-8 はビュー v_101 の受注番号が '10012' の受注個数を 175 から 150 に変更するものです。

-- sample.21-8 --
/* UPDATE */

  UPDATE v_101 SET 受注個数 = 150
    WHERE 受注番号 = '10012' ;

また、行を削除するには DELETE 文を使用します。sample.21-4 で挿入された受注番号 = '10013' の行を削除するには sample.21-9 のように書きます。

-- sample.21-9 --
/* DELETE */

  DELETE FROM v_101
    WHERE 受注番号 = '10013' ;

このように、ビューに対してデータの追加、更新、削除を行う方法は実テーブルに対して行うときと同じように行えます。ただし、ビューは実テーブルから仮想的な表として定義されているものなので、実テーブルに対してデータの追加、更新、削除を行うように自由にはできません。ビューに対するデータの変更には次のような制限があります。

  1. 1つの実テーブルから定義されているビューに対してのみデータの変更が可能です。複数の実テーブルから定義されているビューに対してはデータの変更はできません。
  2. GROUP BY 句及び HAVING 句を使用して定義されたビューに対してはデータの変更ができません。GROUP BY 句及び HAVING 句を用いているクエリは出力するデータの行を特定ができないためです。
  3. DISTINCT 句を使用して定義されたビューに対してはデータの変更ができません。これも GROUP BY 句及び HAVING 句用いているクエリと同様に、出力されるデータの行が特定できないからです

9.4. ビューの削除

  DROP VIEW ビュー名

このとき、ビューは削除されますが、ビューの元になる実テーブルのデータは削除されません。これに対して、ビューを元に定義されたビューは元になるビューが削除されると、そのビューは無効になります。

sample.21-10 では 9.1. 節で定義した v_受注ビューを削除します。

-- sample.21-10 --
/* ビューの削除 */

  DROP VIEW v_受注 ;

↑このページの先頭へ

こちらもチェック!

PR
  • XMLDB.jp