【问题标题】:Oracle DB: How to block drop table statementOracle DB:如何阻止删除表语句
【发布时间】:2021-12-16 19:19:40
【问题描述】:

我需要在 oracle 中使用某些表来限制对 DDL 的访问,禁止删除该表。我怎么能做到这一点?我只是可以为数据库和架构创建 DDL 触发器

create table my_table(
  id int primary key not null,
  first_val int,
  second_val int
);

create trigger delete_disabling_trigger
  before drop on database
begin
  if --some condition
    dbms_output.put_line('delete_disabling_trigger');
    RAISE_APPLICATION_ERROR(-175,'Cant delete this table');
  end if;
end;

【问题讨论】:

    标签: oracle


    【解决方案1】:

    如果您需要某人无法删除的表,您可以在另一个架构中创建该表。授予使用表的用户选择、插入、更新、删除和创建同义词的权限。

    场景:用户 X 需要无法删除的表 T。

    Create user persist identified by password.
    Create table persist.T ...
    GRANT SELECT, INSERT, UPDATE, DELETE on persist.T to X;
    create synonym X.T for persist.T;
    

    在这种情况下,X 可以操作数据但不能更改结构或删除表。使用触发器似乎是阻止删除表的奇怪解决方案。

    编辑

    create or replace trigger delete_disabling_trigger
      before drop on database
    begin
        if(ORA_DICT_OBJ_NAME = 'MY_TABLE') then --and ORA_DICT_OBJ_OWNER = 'YOUR_SCHEMA'  
        dbms_output.put_line('delete_disabling_trigger');
        RAISE_APPLICATION_ERROR(-20000,'Cant delete this table');
        end if;
    end;
    /
    

    【讨论】:

    • 是的,我知道了,谢谢。但不幸的是,我需要使用触发器
    • @Evgeniy175 所以这听起来像是一种家庭作业。通常,您希望在实际应用程序中避免使用触发器。
    • StackOverflow 上关于触发器的大多数问题都来自家庭作业,因为在实际的业务应用程序中,大多数开发人员会尽可能避免触发器。
    • @Evgeniy175 好的,我已经编辑了答案并添加了触发器。这真是太疯狂的事情了。祝你好运。
    • 我希望在我的生活中使用它一次;)谢谢!
    【解决方案2】:

    我刚刚实现了一个触发器来停止删除 5 个表,这些表正在被一些未知的进程从 2 个开发模式中删除。我们在具有自治事务的表中注册尝试,并停止删除。

    我希望尽快确定过程并摆脱触发器。

    CREATE OR REPLACE TRIGGER whos_dropping_my_table
    BEFORE DROP
    ON database
    declare
       PRAGMA AUTONOMOUS_TRANSACTION;
    begin
      insert into some_table_I_prepared_earlier
      VALUES( SUBSTR(ora_sysevent,1,50),
              SUBSTR(ora_dict_obj_owner,1,50),
              SUBSTR(ora_dict_obj_name,1,50),
              SUBSTR(ora_dict_obj_TYPE,1,50),
              UPPER(sys_context('USERENV','TERMINAL')),
              SYSDATE,
              UPPER(sys_context('USERENV','OS_USER'))
            );
      commit;
    
      if SUBSTR(ora_dict_obj_name,1,50) in     
               ('TABLE_1','TABLE_2','TABLE_3','TABLE_4','Table_5')
      then
        begin
          RAISE_APPLICATION_ERROR(num => -20998, 
                            msg => 'Stop deleting my table, whoever you are'); 
        end;
      end if;
    end;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 2012-06-03
      • 2012-04-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多