为什么我不能从select视图(ORACLE)中具有聚合函数的视图中删除行?

时间:2016-06-12 17:40:48

标签: sql oracle view aggregate-functions

我已经阅读过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}的部门不再存在。

1 个答案:

答案 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触发器来解决您想要的问题。