oracle 的view 为什么可以修改、新增到源数据???求解。谢谢!

2024-11-06 14:26:23
推荐回答(4个)
回答1:

单表的视图, 默认是可以修改数据的。


例如 下面这样的视图:


SQL> CREATE VIEW
  2    V_SALE_REPORT
  3  AS
  4    SELECT
  5      *
  6    FROM
  7      SALE_REPORT;

View created.

SQL> INSERT INTO v_sale_report (
  2    sale_date, sale_item, sale_money
  3  ) VALUES (
  4    TO_DATE('2012.01.01', 'YYYY.MM.DD'), 'X', 1
  5  );

1 row created.

SQL> alter session set NLS_DATE_FORMAT="YYYY.MM.DD";

Session altered.

SQL> SELECT
  2    *
  3  FROM
  4    sale_report
  5  WHERE
  6    sale_date = TO_DATE('2012.01.01', 'YYYY.MM.DD');

SALE_DATE  SALE SALE_MONEY
---------- ---- ----------
2012.01.01 X             1



WITH READ ONLY 选项, 将默认的 “可修改” 关闭掉

SQL> CREATE VIEW
  2    v_sale_report_read_only
  3  AS
  4    SELECT
  5      *
  6    FROM
  7      sale_report
  8  WITH READ ONLY;

View created.

SQL> INSERT INTO v_sale_report_read_only (
  2    sale_date, sale_item, sale_money
  3  ) VALUES (
  4    TO_DATE('2012.02.02', 'YYYY.MM.DD'), 'X', 1
  5  );
  sale_date, sale_item, sale_money
  *
ERROR at line 2:
ORA-01733: virtual column not allowed here



WITH CHECK OPTION   选项,  是  “约束可更新”


SQL> CREATE VIEW
  2    v_sale_report_x
  3  AS
  4    SELECT
  5      *
  6    FROM
  7      sale_report
  8    WHERE
  9      sale_item = 'X'
 10  WITH CHECK OPTION;

View created.

SQL> INSERT INTO v_sale_report_x (
  2    sale_date, sale_item, sale_money
  3  ) VALUES (
  4    TO_DATE('2012.02.02', 'YYYY.MM.DD'), 'X', 1
  5  );

1 row created.

SQL>
SQL>
SQL> INSERT INTO v_sale_report_x (
  2    sale_date, sale_item, sale_money
  3  ) VALUES (
  4    TO_DATE('2012.02.02', 'YYYY.MM.DD'), 'Y', 1
  5  );
INSERT INTO v_sale_report_x (
            *
ERROR at line 1:
ORA-01402: view WITH CHECK OPTION where-clause violation



上面是  单表的视图的情况。



下面是 单表统计视图 的情况。

这种 视图里面, 使用到了 SUM () 的, 默认情况下, 是不能  插入,更新,删除处理了。

要通过 INSTEAD OF 关键字实现视图的触发器来实现了


SQL> CREATE VIEW
  2    v_sale_report_sum
  3  AS
  4  SELECT
  5    sale_item,
  6    SUM(sale_money) AS sale_money
  7  FROM
  8    sale_report
  9  GROUP BY
 10    sale_item;

View created.

SQL> SELECT * FROM v_sale_report_sum;

SALE SALE_MONEY
---- ----------
A        733285
B          2382
C          5738
X             1

SQL> DELETE FROM v_sale_report_sum WHERE sale_item = 'X';
DELETE FROM v_sale_report_sum WHERE sale_item = 'X'
            *
ERROR at line 1:
ORA-01732: data manipulation operation not legal on this view

SQL> CREATE OR REPLACE TRIGGER v_sale_report_trigger
  2  INSTEAD OF
  3  DELETE ON v_sale_report_sum
  4  FOR EACH ROW
  5  BEGIN
  6    DELETE FROM sale_report WHERE sale_item = :old.sale_item;
  7  END;
  8  /

Trigger created.

SQL> DELETE FROM v_sale_report_sum WHERE sale_item = 'X';

1 row deleted.

SQL> SELECT * FROM v_sale_report_sum;

SALE SALE_MONEY
---- ----------
A        733285
B          2382
C          5738

回答2:

默认的话,是可修改视图到元数据表里的

所以在建立时需要加一句话在最后
create view 视图名
as

select ....

with read only

比如象上边那样就无法修改了

回答3:

视图本身不保存数据,是对表中数据的映射,如果通过视图修改数据,那么其实修改的是映射的表中的数据

回答4:

也有可能视图上有触发器。