視圖無(wú)非就是存儲(chǔ)在數(shù)據(jù)庫(kù)中并具有名字的 SQL 語(yǔ)句,或者說(shuō)是以預(yù)定義的 SQL 查詢的形式存在的數(shù)據(jù)表的成分。
視圖可以包含表中的所有列,或者僅包含選定的列。視圖可以創(chuàng)建自一個(gè)或者多個(gè)表,這取決于創(chuàng)建該視圖的 SQL 語(yǔ)句的寫(xiě)法。
視圖,一種虛擬的表,允許用戶執(zhí)行以下操作:
數(shù)據(jù)庫(kù)視圖由 CREATE VIEW 語(yǔ)句創(chuàng)建。視圖可以創(chuàng)建自單個(gè)表、多個(gè)表或者其他視圖。
要?jiǎng)?chuàng)建視圖的話,用戶必須有適當(dāng)?shù)南到y(tǒng)權(quán)限。具體需要何種權(quán)限隨數(shù)據(jù)庫(kù)系統(tǒng)實(shí)現(xiàn)的不同而不同。
CREATE VIEW 語(yǔ)句的基本語(yǔ)法如下所示:
CREATE VIEW view_name AS
SELECT column1, column2.....
FROM table_name
WHERE [condition];
和普通的 SQL SELECT 查詢一樣,你可以在上面的 SELECT 語(yǔ)句中包含多個(gè)數(shù)據(jù)表。
考慮 CUSTOMERS 表,表中的記錄如下所示:
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+-----------+----------+
下面是由 CUSTOMERS 表創(chuàng)建視圖的例子。該視圖包含來(lái)自 CUSTOMERS 表的顧客的名字(name)和年齡(age):
SQL > CREATE VIEW CUSTOMERS_VIEW AS
SELECT name, age
FROM CUSTOMERS;
現(xiàn)在,你就可以像查詢普通的數(shù)據(jù)表一樣查詢 CUSTOMERS_VIEW 了:
SQL > SELECT * FROM CUSTOMERS_VIEW;
上述語(yǔ)句將會(huì)產(chǎn)生如下運(yùn)行結(jié)果:
+----------+-----+
| name | age |
+----------+-----+
| Ramesh | 32 |
| Khilan | 25 |
| kaushik | 23 |
| Chaitali | 25 |
| Hardik | 27 |
| Komal | 22 |
| Muffy | 24 |
+----------+-----+
WITH CHECK OPTION 是 CREATE VIEW 語(yǔ)句的一個(gè)可選項(xiàng)。WITH CHECK OPTION 用于保證所有的 UPDATE 和 INSERT 語(yǔ)句都滿足視圖定義中的條件。
如果不能滿足這些條件,UPDATE 或 INSERT 就會(huì)返回錯(cuò)誤。
下面的例子創(chuàng)建的也是 CUSTOMERS_VIEW 視圖,不過(guò)這次 WITH CHECK OPTION 是打開(kāi)的:
CREATE VIEW CUSTOMERS_VIEW AS
SELECT name, age
FROM CUSTOMERS
WHERE age IS NOT NULL
WITH CHECK OPTION;
這里 WITH CHECK OPTION 使得視圖拒絕任何 AGE 字段為 NULL 的條目,因?yàn)橐晥D的定義中,AGE 字段不能為空。
視圖可以在特定的情況下更新:
如果視圖滿足以上所有的條件,該視圖就可以被更新。下面的例子中,Ramesh 的年齡被更新了:
SQL > UPDATE CUSTOMERS_VIEW
SET AGE = 35
WHERE name='Ramesh';
最終更新的還是原始數(shù)據(jù)表,只是其結(jié)果反應(yīng)在了視圖上。現(xiàn)在查詢?cè)紨?shù)據(jù)表,SELECT 語(yǔ)句將會(huì)產(chǎn)生以下結(jié)果:
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 35 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+-----------+----------+
可以向視圖中插入新行,其規(guī)則同(使用 UPDATE 命令)更新視圖所遵循的規(guī)則相同。
這里我們不能向 CUSTOMERS_VIEW 視圖中添加新行,因?yàn)樵撘晥D沒(méi)有包含原始數(shù)據(jù)表中所有 NOT NULL 的列。否則的話,你就可以像在數(shù)據(jù)表中插入新行一樣,向視圖中插入新行。
視圖中的數(shù)據(jù)行可以被刪除。刪除數(shù)據(jù)行與更新視圖和向視圖中插入新行遵循相同的規(guī)則。
下面的例子將刪除 CUSTOMERS_VIEW 視圖中 AGE=22 的數(shù)據(jù)行:
SQL > DELETE FROM CUSTOMERS_VIEW
WHERE age = 22;
該語(yǔ)句最終會(huì)將原始數(shù)據(jù)表中對(duì)應(yīng)的數(shù)據(jù)行刪除,只不過(guò)其結(jié)果反應(yīng)在了視圖上?,F(xiàn)在查詢?cè)紨?shù)據(jù)表,SELECT 語(yǔ)句將會(huì)產(chǎn)生以下結(jié)果:
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 35 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+-----------+----------+
很明顯,當(dāng)我們不再需要某個(gè)視圖的時(shí)候,需要有一種方式可以讓我們將其刪除。刪除視圖的語(yǔ)法非常簡(jiǎn)單,如下所示:
DROP VIEW view_name;
下面的例子展示了如何從 CUSTOMERS 表中刪除 CUSTOMERS_VIEW 視圖:
DROP VIEW CUSTOMERS_VIEW;