Oracle视图 #
一、视图概述 #
1.1 什么是视图 #
视图是一个或多个表的逻辑表示,它存储查询定义而不存储数据。视图可以简化复杂查询、提供数据安全性和逻辑数据独立性。
text
视图类型
├── 简单视图
│ └── 基于单个表,无函数
├── 复杂视图
│ └── 多表连接,包含函数
├── 可更新视图
│ └── 允许DML操作
└── 只读视图
└── 不允许DML操作
二、创建视图 #
2.1 基本语法 #
sql
-- 创建视图基本语法
CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view_name
[(alias1, alias2, ...)]
AS
SELECT statement
[WITH CHECK OPTION [CONSTRAINT constraint_name]]
[WITH READ ONLY];
2.2 创建简单视图 #
sql
-- 创建简单视图
CREATE OR REPLACE VIEW emp_view AS
SELECT employee_id, first_name, last_name, salary
FROM employees
WHERE department_id = 10;
-- 使用视图
SELECT * FROM emp_view;
-- 创建带别名的视图
CREATE OR REPLACE VIEW emp_view (
emp_id, emp_name, emp_salary
) AS
SELECT employee_id, first_name || ' ' || last_name, salary
FROM employees
WHERE department_id = 10;
2.3 创建复杂视图 #
sql
-- 创建多表连接视图
CREATE OR REPLACE VIEW emp_dept_view AS
SELECT
e.employee_id,
e.first_name,
e.last_name,
e.salary,
d.department_name,
l.city
FROM employees e
JOIN departments d ON e.department_id = d.department_id
JOIN locations l ON d.location_id = l.location_id;
-- 创建包含聚合函数的视图
CREATE OR REPLACE VIEW dept_stats_view AS
SELECT
department_id,
COUNT(*) AS employee_count,
AVG(salary) AS avg_salary,
MAX(salary) AS max_salary,
MIN(salary) AS min_salary
FROM employees
GROUP BY department_id;
三、可更新视图 #
3.1 可更新视图条件 #
sql
-- 可更新视图条件:
-- 1. 不包含聚合函数
-- 2. 不包含DISTINCT
-- 3. 不包含GROUP BY
-- 4. 不包含集合运算
-- 5. 不包含ROWNUM伪列
-- 创建可更新视图
CREATE OR REPLACE VIEW emp_update_view AS
SELECT employee_id, first_name, last_name, salary
FROM employees
WHERE department_id = 10;
-- 通过视图插入
INSERT INTO emp_update_view VALUES (999, 'Test', 'User', 5000);
-- 通过视图更新
UPDATE emp_update_view SET salary = 6000 WHERE employee_id = 999;
-- 通过视图删除
DELETE FROM emp_update_view WHERE employee_id = 999;
3.2 WITH CHECK OPTION #
sql
-- WITH CHECK OPTION:确保DML操作后的数据仍在视图中
CREATE OR REPLACE VIEW emp_dept_10_view AS
SELECT employee_id, first_name, last_name, salary, department_id
FROM employees
WHERE department_id = 10
WITH CHECK OPTION;
-- 允许:更新后仍在视图中
UPDATE emp_dept_10_view SET salary = 6000 WHERE employee_id = 100;
-- 不允许:更新后不在视图中
UPDATE emp_dept_10_view SET department_id = 20 WHERE employee_id = 100;
-- ORA-01402: view WITH CHECK OPTION where-clause violation
3.3 WITH READ ONLY #
sql
-- 创建只读视图
CREATE OR REPLACE VIEW emp_readonly_view AS
SELECT employee_id, first_name, last_name, salary
FROM employees
WHERE department_id = 10
WITH READ ONLY;
-- 不允许DML操作
-- INSERT INTO emp_readonly_view VALUES (999, 'Test', 'User', 5000);
-- ORA-42399: cannot perform a DML operation on a read-only view
四、视图管理 #
4.1 查看视图 #
sql
-- 查看视图定义
SELECT view_name, text FROM user_views;
-- 查看视图详细信息
SELECT * FROM user_views WHERE view_name = 'EMP_VIEW';
-- 查看视图列
SELECT column_name, data_type, nullable
FROM user_tab_columns
WHERE table_name = 'EMP_VIEW';
-- 使用DESC命令
DESC emp_view;
4.2 修改视图 #
sql
-- 使用CREATE OR REPLACE修改视图
CREATE OR REPLACE VIEW emp_view AS
SELECT employee_id, first_name, last_name, salary, hire_date
FROM employees
WHERE department_id = 10;
4.3 删除视图 #
sql
-- 删除视图
DROP VIEW emp_view;
-- 删除不存在的视图(避免错误)
DROP VIEW IF EXISTS emp_view;
五、内联视图 #
5.1 内联视图使用 #
sql
-- 内联视图:FROM子句中的子查询
SELECT e.employee_id, e.first_name, d.department_name
FROM (
SELECT employee_id, first_name, department_id
FROM employees
WHERE salary > 10000
) e
JOIN departments d ON e.department_id = d.department_id;
-- 使用内联视图进行分页
SELECT *
FROM (
SELECT e.*, ROWNUM rn
FROM (
SELECT * FROM employees ORDER BY salary DESC
) e
WHERE ROWNUM <= 10
)
WHERE rn > 5;
六、视图最佳实践 #
6.1 视图命名规范 #
sql
-- 推荐:使用v_或view_前缀
CREATE OR REPLACE VIEW v_employee_details AS ...
CREATE OR REPLACE VIEW view_dept_stats AS ...
6.2 视图使用场景 #
sql
-- 1. 简化复杂查询
CREATE OR REPLACE VIEW v_emp_full_info AS
SELECT e.*, d.department_name, l.city
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id
LEFT JOIN locations l ON d.location_id = l.location_id;
-- 2. 数据安全
CREATE OR REPLACE VIEW v_emp_public AS
SELECT employee_id, first_name, last_name
FROM employees; -- 隐藏敏感列如salary
-- 3. 业务逻辑封装
CREATE OR REPLACE VIEW v_active_employees AS
SELECT * FROM employees
WHERE status = 'ACTIVE' AND hire_date <= SYSDATE;
七、总结 #
视图要点:
| 类型 | 特点 | DML支持 |
|---|---|---|
| 简单视图 | 单表,无函数 | 支持 |
| 复杂视图 | 多表,有函数 | 受限 |
| 只读视图 | WITH READ ONLY | 不支持 |
最佳实践:
- 视图用于简化查询和封装逻辑
- 注意可更新视图的限制
- 使用WITH CHECK OPTION保证数据一致性
- 避免嵌套过多视图
- 定期检查视图依赖关系
下一步,让我们学习物化视图!
最后更新:2026-03-27