【问题标题】:Check whether a tables exist or not on another schema - ORACLE DB检查表是否存在于另一个模式 - ORACLE DB
【发布时间】:2014-01-02 17:49:50
【问题描述】:

我有一个由 EMP_DBA 创建的存储过程,部分查询将检查现有表是否存在,如果存在则删除表。如果我以 EMP_DBA 身份连接,则此查询工作正常,现在我想使用其他帐户运行此存储过程,比如说 USER1,并且我已将所有必要的权限授予 USER1。如果表 MARKET_DATA 存在于模式 EMP_DBA 中,如何重写下面的语句以返回 1?

BEGIN 
SELECT COUNT(*) INTO c
FROM all_tables
WHERE
table_name = 'MARKET_DATA' AND OWNER = 'EMP_DBA';

IF C = 1 THEN
EXECUTE IMMEDIATE 'DROP TABLE MARKET_DATA';
--exception when others then null; 
END IF;

【问题讨论】:

    标签: oracle security plsql oracle11g schema


    【解决方案1】:

    “我已将所有必要的权限授予 USER1”

    这是一个有点令人担忧的声明。 所有必要的权利是什么意思?唯一合适的权限是在 EMP_DBA 拥有的存储过程上执行。该过程应该封装所有内容。 EMP_DBA 不(或不应该)希望 USER1 独立删除他们的表。此外,不可能在特定对象甚至特定模式上授予 DDL 语句。 DROP ANY 是一项强大的分发特权。

    编写存储过程的最佳方式是使用定义者的权限(这是默认设置)。这确保代码以存储过程所有者的权限执行,而不是执行用户的权限。您的代码不起作用 - 可能是因为您没有指定表所有者 - 表明您的安全模型没有完全正确。

    在我的版本中,我像您一样使用了 ALL_TABLES,以显示 CURRENT_USER 和 SESSION_USER 之间的区别,但实际上 USER_TABLES 也可以正常工作。

    create or replace procedure recreate_tab
        (p_tab_name in all_tables.table_name%type)
        authid definer
    is
        n pls_integer;
    begin
        select count(*)
        into n
        from all_tables
        where owner = (sys_context('userenv','current_user'))
        and table_name = p_tab_name;
    
        if n = 1
        then
            -- no need to specify schema because it's the procedure owner
            execute immediate 'drop table '|| p_tab_name;
        end if;
    
        execute immediate 'create table '||p_tab_name
            ||' ( id number, descr varchar2(30))';
    
        -- grant rights on the new table to the user executing the procedure
        execute immediate 'grant select on '||p_tab_name||' to '
            || sys_context('userenv','session_user');
    end recreate_tab;
    /
    
    grant execute on recreate_tab to user1
    /
    

    所以。我的袖手旁观...

    SQL> conn user1/user1
    Connected.
    SQL> select count(*) from t42
      2  /
    select count(*) from t42
                 *
    ERROR at line 1:
    ORA-00942: table or view does not exist
    
    
    SQL> select count(*) from emp_dba.t42
      2  /
    
      COUNT(*)
    ----------
         56179
    
    SQL> exec emp_dba.recreate_tab('T42')
    
    PL/SQL procedure successfully completed.
    
    SQL> select count(*) from emp_dba.t42
      2  /
    
      COUNT(*)
    ----------
         0
    
    SQL> 
    

    【讨论】:

      【解决方案2】:

      您的选择是正确的。你应该重写 EXECUTE IMMEDIATE 来做

      DROP TABLE EMP_DBA.MARKET_DATA
      

      【讨论】:

        猜你喜欢
        • 2018-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-02
        相关资源
        最近更新 更多