检查另一个模式(ORACLE DB)上是否存在表

时间:2013-12-15 07:29:14

标签: oracle security plsql oracle11g schema

我有一个由EMP_DBA创建的存储过程,部分查询将检查现有表是否存在,如果存在则删除表。如果我作为EMP_DBA连接,此查询工作正常,现在我想与其他帐户运行此存储过程,比如USER1,我已经授予USER1所有必要的权限。如果在架构EMP_DBA中存在表MARKET_DATA,如何在order count中重写下面的语句?

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;

2 个答案:

答案 0 :(得分:0)

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

DROP TABLE EMP_DBA.MARKET_DATA

答案 1 :(得分:0)

  
    

“我已向USER1授予所有必要的权利”

  

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

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

在我的版本我使用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>