8.ビュー

ビューとは、CREATE TABLE で定義された実テーブルから作成される仮想的なテーブルのことです。ビューはあくまでも仮想テーブルなので、その中にデータは存在しません。ビューは実テーブルをどのように見るのかを定義したものと言えます。

もうすでに使っていますが、CREATE TABLE で定義された、データの入ったテーブルのことを実テーブル、この実テーブルから作られる仮想的なテーブルをビューと呼ぶことにします。

8.1. ビューのメリット

ビューの実体は SELECT 文によるクエリを定義したものです。ビューにアクセスすると、定義されたクエリが実行され、実テーブルから必要なデータが抽出されます。また、ビューからビューを定義することも可能です。ですから、あらかじめ毎回入力するのが面倒な複雑なクエリを一度ビューとして定義しておけば、ユーザやプログラムは単純なクエリを実行するだけですみます。

このような開発労力の軽減という観点以外に、セキュリティについてもメリットもあります。たとえば、実テーブルのデータの中に一般ユーザには見せたくないものがある場合、実テーブルへのアクセス権限を一般ユーザには与えることはできません。しかし、見せたくないデータを除いたビューを定義することにより、一般ユーザでも実テーブルのデータを利用できるようになります。

8.2. ビューの作成

ビューを作成するには CREATE VIEW 文を用います。基本構文は次のとおりです。

1
2
3
4
CREATE VIEW viewname [(列名1, 列名2, ...列名n)]
AS
SELECT文
[WITH CHECK OPTION];

ビュー名の後には、抽出するデータの列名を記述します。列名を省略した場合、SELECT 文で指定した列の名前がそのまま使用されます。SELECT 文で演算子を使用した場合や、改めて列名を指定したい場合に明示的に記述するものです。

ビュー名と列名の後には、AS に続けて SELECT 文によるクエリを記述します。このクエリの結果がこのビューのデータということになります。[WITH CHECK OPTION] はビューの更新に関連するオプションです。ビューの更新については後の節で説明します。

この章の SQL のサンプルはこれまでの章でも使用してきた 受注表・顧客表・商品表 を実テーブルとして使用します。 sample-08-1 では v_受注という名前のビューを定義し、最後にビューの内容を確認しています。

sample-08-1:

1
2
3
4
5
6
7
/* ビューの作成 */
CREATE VIEW v_受注
AS
SELECT JJ.受注番号, KK.顧客名, SS.商品名,
       JJ.受注個数, JJ.納品日
FROM 受注表 JJ, 顧客表 KK, 商品表 SS
WHERE JJ.顧客コード = KK.顧客コード AND JJ.商品コード = SS.商品コード ;
1
2
3
4
5
/* 確認 */
SELECT JJ.受注番号, KK.顧客名, SS.商品名,
       JJ.受注個数, JJ.納品日
FROM 受注表 JJ, 顧客表 KK, 商品表 SS
WHERE JJ.顧客コード = KK.顧客コード AND JJ.商品コード = SS.商品コード ;

確認の実行結果

ビュー確認

1
SELECT * FROM v_受注 ;

.ビュー確認の実行結果

定義したビューから特定の行や列を出力することも出来ます。 sample-08-2 は定義したv_受注から、受注個数が 100以上である行を選択し、その顧客名、商品名及び受注個数を出力するものです。

sample-08-2:

1
2
3
4
/* ビューからの抽出 */
SELECT 顧客名,商品名,受注個数  
FROM v_受注
WHERE 受注個数 >= 100 ;

実行結果

8.3. ビューの変更

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

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

sample-08-3:ビューの作成(v_101)

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

確認実行結果

➊データの追加は INSERT 文を用います。
下記のSQL文は、SQLiteで実行することができません
sample-08-4 ビュー v_101 に対して、受注番号 = '10013'、顧客コード = '002'、受注個数 = 120、納品日 = '20010406' の行を追加します。

sample-08-4:

1
2
/* INSERT */
INSERT INTO v_101 VALUES('10013', '002', '101', 120, '20010406') ;

➋データの更新は UPDATE 文を用います。
下記のSQL文は、SQLiteで実行することができません
sample-08-5 はビュー v_101 の受注番号が '10012' の受注個数を 175 から 150 に変更するものです。

sample-08-5:

1
2
3
/* UPDATE */
UPDATE v_101 SET 受注個数 = 150
WHERE 受注番号 = '10012' ;

➌行を削除するには DELETE 文を使用します。
下記のSQL文は、SQLiteで実行することができません
行を削除するには sample-08-6 のように書きます。
sample-08-6:

1
2
3
/* DELETE */
DELETE FROM v_101
WHERE 受注番号 = '10012' ;

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

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

8.4. ビューの削除

1
DROP VIEW viewname

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

sample-08-7 では 8.1. 節で定義した v_受注ビューを削除します。

sample-08-7:

1
2
/* ビューの削除 */
DROP VIEW v_受注 ;

8.5 SQL文

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
CREATE VIEW v_受注 AS
SELECT JJ.受注番号, KK.顧客名, SS.商品名,
       JJ.受注個数, JJ.納品日
FROM 受注表 JJ, 顧客表 KK, 商品表 SS
WHERE JJ.顧客コード = KK.顧客コード
AND JJ.商品コード = SS.商品コード ;

SELECT JJ.受注番号, KK.顧客名, SS.商品名,
       JJ.受注個数, JJ.納品日
FROM 受注表 JJ, 顧客表 KK, 商品表 SS
WHERE JJ.顧客コード = KK.顧客コード
AND JJ.商品コード = SS.商品コード ;

SELECT * FROM v_受注 ;

SELECT 顧客名,商品名,受注個数 FROM v_受注
WHERE 受注個数 >= 100 ;  

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

SELECT * FROM v_101 ;

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

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

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

DROP VIEW v_受注 ;