在本教程中,您將學(xué)習(xí)如何使用SQL創(chuàng)建,更新和刪除視圖。
視圖是一個虛擬表,其定義存儲在數(shù)據(jù)庫中。但是,與表不同,視圖實際上不包含任何數(shù)據(jù)。相反,它提供了一種在數(shù)據(jù)庫中存儲常用復(fù)雜查詢的方法。但是,您可以使用SQL SELECT語句來訪問視圖數(shù)據(jù),就像使用普通表或基表一樣。
通過允許用戶通過視圖訪問數(shù)據(jù),而不是直接授予整個基表訪問權(quán)限,視圖也可以用作安全機制。
使用CREATE VIEW語句創(chuàng)建視圖。
CREATE VIEW view_name AS select_statement;
為了清楚地理解這一點,讓我們來看看下面employees和departments表。
+--------+--------------+--------+---------+ | emp_id | emp_name | salary | dept_id | +--------+--------------+--------+---------+ | 1 | Ethan Hunt | 5000 | 4 | | 2 | Tony Montana | 6500 | 1 | | 3 | Sarah Connor | 8000 | 5 | | 4 | Rick Deckard | 7200 | 3 | | 5 | Martin Blank | 5600 | NULL | +--------+--------------+--------+---------+ | +---------+------------------+ | dept_id | dept_name | +---------+------------------+ | 1 | Administration | | 2 | Customer Service | | 3 | Finance | | 4 | Human Resources | | 5 | Sales | +---------+------------------+ | |
表: employees | 表: departments |
假設(shè)您要檢索雇員的ID和姓名以及他們的部門名稱,那么您需要執(zhí)行左加入操作,如下所示:
SELECT t1.emp_id, t1.emp_name, t2.dept_name FROM employees AS t1 LEFT JOIN departments AS t2 ON t1.dept_id = t2.dept_id;
一旦執(zhí)行了上面的查詢,您將獲得如下輸出:
+--------+--------------+-----------------+ | emp_id | emp_name | dept_name | +--------+--------------+-----------------+ | 1 | Ethan Hunt | Human Resources | | 2 | Tony Montana | Administration | | 3 | Sarah Connor | Sales | | 4 | Rick Deckard | Finance | | 5 | Martin Blank | NULL | +--------+--------------+-----------------+
但是,無論何時要訪問此記錄,都需要再次鍵入整個查詢。如果您經(jīng)常執(zhí)行此類操作,則將變得非常不便和煩人。
在這種情況下,您可以創(chuàng)建一個視圖以使查詢結(jié)果更易于訪問,如下所示:
CREATE VIEW emp_dept_view AS SELECT t1.emp_id, t1.emp_name, t2.dept_name FROM employees AS t1 LEFT JOIN departments AS t2 ON t1.dept_id = t2.dept_id;
現(xiàn)在,您可以使用視圖emp_dept_view訪問相同的記錄,如下所示:
SELECT * FROM emp_dept_view;
正如您看到的,您可以在視圖上節(jié)省多少時間和精力。
提示:視圖始終顯示最新數(shù)據(jù)!每次查詢視圖時,數(shù)據(jù)庫引擎都會執(zhí)行與視圖關(guān)聯(lián)的SQL查詢并重新創(chuàng)建數(shù)據(jù)。
在MySQL中,如果要更新或替換現(xiàn)有視圖,則可以刪除該視圖并創(chuàng)建一個新視圖,或者只使用CREATE VIEW語句中的OR REPLACE子句,如下所示:
CREATE OR REPLACE VIEW view_name AS select_statement;
注意:在CREATE VIEW語句中使用OR REPLACE子句時,如果該視圖不存在,它將創(chuàng)建一個新視圖,否則將替換現(xiàn)有視圖。
下面的SQL語句將替換或更改現(xiàn)有視圖emp_dept_view視圖的定義,方法是向其添加一個新列salary。
-- MySQL數(shù)據(jù)庫的語法 CREATE OR REPLACE VIEW emp_dept_view AS SELECT t1.emp_id, t1.emp_name, t1.salary, t2.dept_name FROM employees AS t1 LEFT JOIN departments AS t2 ON t1.dept_id = t2.dept_id;
更新視圖后,如果執(zhí)行以下語句:
SELECT * FROM emp_dept_view ORDER BY emp_id;
您將在結(jié)果輸出中看到另一列salary,如下所示:
+--------+--------------+--------+-----------------+ | emp_id | emp_name | salary | dept_name | +--------+--------------+--------+-----------------+ | 1 | Ethan Hunt | 5000 | Human Resources | | 2 | Tony Montana | 6500 | Administration | | 3 | Sarah Connor | 8000 | Sales | | 4 | Rick Deckard | 7200 | Finance | | 5 | Martin Blank | 5600 | NULL | +--------+--------------+--------+-----------------+
注意: SQL Server不支持OR REPLACE子句,因此,要替換視圖,您可以直接刪除該視圖并從stretch中創(chuàng)建一個新視圖。
從理論上講,除了SELECT語句外,您還可以在視圖上執(zhí)行INSERT,UPDATE和DELETE。 但是,并非所有視圖都是可更新的,即能夠修改基礎(chǔ)源表的數(shù)據(jù)。 對可更新性有一些限制。
通常,如果視圖包含以下任何內(nèi)容,則該視圖不可更新:
DISTINCT,GROUP BY或HAVING子句。
聚合函數(shù),例如AVG(),COUNT(),SUM(),MIN(),MAX()等等。
UNION,UNION ALL,CROSSJOIN,EXCEPT或INTERSECT運算符。
WHERE子句中的子查詢引用FROM子句中的表。
如果一個視圖滿足這些條件,則可以使用該視圖修改源表。
以下語句將更新emp_id等于1的員工的薪水(salary)。
UPDATE emp_dept_view SET salary = '6000' WHERE emp_id = 1;
注意:為了實現(xiàn)可插入性,該視圖必須包含基表中所有沒有默認(rèn)值的列。 同樣,為了實現(xiàn)可更新性,視圖中的每個可更新列必須與源表中的可更新列相對應(yīng)。
同樣,如果不再需要視圖,則可以使用DROP VIEW語句將其從數(shù)據(jù)庫中刪除,如以下語法所示:
DROP VIEW view_name;
以下命令將從數(shù)據(jù)庫中刪除視圖emp_dept_view。
DROP VIEW emp_dept_view;