我已经阅读过ORACLE中带有视图的DML操作规则。他们中的大多数似乎都很清楚,但我对聚合功能感到困惑。
例如,我有两张桌子。
EMPLOYEES
╔═══════════╦═════════════╦══════════╗
║ emp_id ║ salary ║ dept_id ║
╠═══════════╬═════════════╬══════════╣
║ 2134 ║ 2200 ║ 10 ║
║ 2327 ║ 3100 ║ 10 ║
║ 2428 ║ 4100 ║ 20 ║
║ 2637 ║ 1700 ║ 30 ║
╚═══════════╩═════════════╩══════════╝
\ | /
\|/
|
| DEPARTMENTS
╔═══════════╦═════════════╦══════════╗
║ dept_id ║ dname ║ location ║
╠═══════════╬═════════════╬══════════╣
║ 10 ║ ║ ║
║ 20 ║ ║ ║
║ 30 ║ ║ ║
╚═══════════╩═════════════╩══════════╝
我想要一个按部门显示员工平均工资的视图。 所以,我运行这个SQL:
CREATE OR REPLACE VIEW dept_sals AS
SELECT d.dept_id, round(avg(e.salary)) AS avg_salary
FROM employees e
JOIN
departments d
ON (e.dept_id = d.dept_id)
GROUP BY d.dept_id;
现在我的观点如下:
╔═══════════╦════════════╗
║ dept_id ║ avg_salary ║
╠═══════════╬════════════╣
║ 10 ║ 2650 ║
║ 20 ║ 4100 ║
║ 30 ║ 1700 ║
╚═══════════╩════════════╝
我明白为什么我不能对这个视图运行update语句。列“avg_salary”不是数据,它是动态生成的信息。但为什么我不能从这个视图中删除一行?
如果我尝试跑步:
delete from dept_sals where dept_id = 10;
我明白了:
ORA-01732: data manipulation operation not legal on this view
我在想什么:
基表DEPARTMENTS与此视图中的行具有一对一的关系。 我想Oracle可以从视图中获取{dept_id}并生成从DEPARTMENTS表中删除相应行的SQL。这不会损害表的一致性,因为“avg_salary”中的信息不是数据,这是我们可以丢弃的计算,因为{dept_id}的部门不再存在。
答案 0 :(得分:5)
您指定的是Oracle中不可更新的视图。此处从Oracle文档中指定了可分隔可更新和不可更新视图的规则。
"如果视图查询包含以下任何结构,则UPDATE,INSERT或DELETE语句不能修改视图:
A set operator
A DISTINCT operator
An aggregate or analytic function
A GROUP BY, ORDER BY, MODEL, CONNECT BY, or START WITH clause
A collection expression in a SELECT list
A subquery in a SELECT list
A subquery designated WITH READ ONLY
Joins, with some exceptions, as documented in Oracle Database Administrator's Guide"
link - > https://docs.oracle.com/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm
您可以通过使用Oracle INSTEAD OF触发器来解决您想要的问题。