视图概述
替代复杂查询,减少复杂性。将复杂的查询语句定义为视图,然后使用视图进行查询,可以隐藏具体的实现;
提供一致性接口,实现业务规则。在视图的定义中增加业务逻辑,对外提供统一的接口;当底层表结构发生变化时,只需要修改视图接口,而不需要修改外部应用,可以简化代码的维护并减少错误;
控制对于表的访问,提高安全性。通过视图为用户提供数据访问,而不是直接访问表;同时可以限制允许访问某些敏感信息,例如身份证号、工资等。
创建视图
CREATE VIEW view_name AS query;
create view emp_details_view
as select
e.employee_id,
e.job_id,
e.manager_id,
e.department_id,
d.location_id,
e.first_name,
e.last_name,
e.salary,
e.commission_pct,
d.department_name,
j.job_title
from employees e
join departments d on (e.department_id = d.department_id)
join jobs j on (j.job_id = e.job_id);
select * from emp_details_view
where department_name = 'IT';
修改视图
CREATE OR REPLACE view_name
AS
query
create or replace view emp_details_view
as select
e.employee_id,
e.job_id,
e.manager_id,
e.department_id,
d.location_id,
e.first_name,
e.last_name,
e.salary,
e.commission_pct,
d.department_name,
j.job_title,
e.hire_date
from employees e
join departments d on (e.department_id = d.department_id)
join jobs j on (j.job_id = e.job_id);
alter view emp_details_view rename to emp_info_view;
删除视图
DROP VIEW [ IF EXISTS ] name [ CASCADE | RESTRICT ];
drop view emp_info_view;
递归视图
CREATE RECURSIVE VIEW view_name (column_names) AS query;
CREATE VIEW view_name AS
WITH RECURSIVE cte_name (column_names) AS (query)
SELECT column_names FROM cte_name;
create recursive view employee_path(employee_id, employee_name, path) as
select employee_id, CONCAT(first_name, ',', last_name), CONCAT(first_name, ',', last_name) as path
from employees
where manager_id is null
union all
select e.employee_id, CONCAT(e.first_name, ',', e.last_name), CONCAT(ep.path, '->', e.first_name, ',', e.last_name)
from employee_path ep
join employees e on ep.employee_id = e.manager_id;
可更新视图
视图定义的 FROM 子句中只包含一个表或者可更新视图;
视图定义的最顶层查询语句中不包含以下子句:GROUP BY、HAVING、LIMIT、OFFSET、DISTINCT、WITH、UNION、INTERSECT 以及 EXCEPT;
SELECT 列表中不包含窗口函数、集合函数或者聚合函数(例如 SUM、COUNT、AVG 等)。
create view employees_it as
select employee_id,
first_name,
last_name,
email,
phone_number,
hire_date,
job_id,
manager_id,
department_id
from employees
where department_id = 60;
select employee_id,first_name, last_name from employees_it;
employee_id|first_name|last_name|
-----------|----------|---------|
103|Alexander |Hunold |
104|Bruce |Ernst |
105|David |Austin |
106|Valli |Pataballa|
107|Diana |Lorentz |
INSERT INTO employees_it
(employee_id, first_name, last_name, email, phone_number, hire_date, job_id, manager_id, department_id)
VALUES(207, 'Tony', 'Dong', 'DONG', '590.423.5568', '2020-05-06', 'IT_PROG', 103, 60);
select employee_id,first_name, last_name from employees_it;
employee_id|first_name|last_name|
-----------|----------|---------|
103|Alexander |Hunold |
104|Bruce |Ernst |
105|David |Austin |
106|Valli |Pataballa|
107|Diana |Lorentz |
207|Tony |Dong |
update employees_it
set salary = 5000
where employee_id = 207;
SQL Error [42703]: ERROR: column "salary" of relation "employees_it" does not exist
Position: 26
delete from employees_it
where employee_id = 207;
WITH CHECK OPTION
INSERT INTO employees_it
(employee_id, first_name, last_name, email, phone_number, hire_date, job_id, manager_id, department_id)
VALUES(207, 'Tony', 'Dong', 'DONG', '590.423.5568', '2020-05-06', 'IT_PROG', 149, 80);
select employee_id,first_name, last_name
from employees_it
where employee_id = 207;
employee_id|first_name|last_name|
-----------|----------|---------|
select employee_id,first_name, last_name
from employees
where employee_id = 207;
employee_id|first_name|last_name|
-----------|----------|---------|
207|Tony |Dong |
create or replace view employees_it as
select employee_id,
first_name,
last_name,
email,
phone_number,
hire_date,
job_id,
manager_id,
department_id
from employees
where department_id = 60
with check option;
delete from employees
where employee_id = 207;
INSERT INTO employees_it
(employee_id, first_name, last_name, email, phone_number, hire_date, job_id, manager_id, department_id)
VALUES(207, 'Tony', 'Dong', 'DONG', '590.423.5568', '2020-05-06', 'IT_PROG', 149, 80);
SQL Error [44000]: ERROR: new row violates check option for view "employees_it"
Detail: Failing row contains (207, Tony, Dong, DONG, 590.423.5568, 2020-05-06, IT_PROG, null, null, 149, 80).