【问题标题】:Oracle trigger for allowing DML on view允许查看 DML 的 Oracle 触发器
【发布时间】:2015-07-15 12:29:40
【问题描述】:

我在 Oracle DB 中有视图:

  CREATE VIEW view1
AS SELECT
  id, c1, c2, c3, c4, c5, c6
FROM
  table1
WHERE
  c1>1100 AND c1<2000
WITH CHECK OPTION;

还有表 table1 的列 id、c1、... c9。 现在我想在此视图上创建触发器,以允许对不在此视图中的数据进行 DML 操作。但我不知道哪些列将被更新,哪些行将被删除或插入。例如

UPDATE view1 SET c1=3000 WHERE c1=1500;

INSERT INTO view1 VALUES(3500, .......);

有人有想法吗?

编辑:我知道,这没有意义,但这是我项目的一部分,这部分将展示如何绕过视图的约束。

【问题讨论】:

    标签: sql database oracle view triggers


    【解决方案1】:

    所以这里是删除的解决方案:

    CREATE OR REPLACE TRIGGER DML_VIEW_DELETE
        INSTEAD OF DELETE ON myview
    BEGIN
        DELETE table
        WHERE id = :old.id;
    END;
    

    类似的更新和插入仅使用:new 而不是:oldnull 在不在视图中的列中

    【讨论】:

      【解决方案2】:

      您似乎试图通过视图插入/更新,同时绕过视图施加的约束——这似乎没有多大意义。无论哪种方式,我认为您不需要在此处使用其他解决方法,例如触发器。

      一般来说,由于您的视图只使用一个表,您可以在不使用触发器等的情况下通过视图进行更新,前提是您保持在c1 (i.e. between 1100 and 2000)CHECK OPTION 范围内:

      INSERT INTO view1(c1, ...) 
      VALUES (1101, );
      
      UPDATE view1 
      SET c1 = 1102 
      WHERE id = 1;
      

      但不是这个:

      UPDATE view1 
      SET c1 = 23 
      WHERE id = 1;
      
      -- ORA-01402: view WITH CHECK OPTION where-clause violation
      

      但是,如果你想绕过约束,你可以:

      • 直接插入/更新表格(即update table1 set c1 = 23 where ...
      • 创建另一个不使用 WHERE 过滤器和 CHECK CONSTRAINT 的视图,然后通过它进行更新(但同样,为什么?)

      我添加了一个 SqlFiddle here 显示上述方法

      【讨论】:

      • 我知道,这根本没有意义,但这是我项目的一部分,展示如何绕过视图约束,我不知道如何实现。我不知道如何开始或先做什么......
      猜你喜欢
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多