繁体   English   中英

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

[英]Check whether a tables exist or not on another schema - ORACLE DB

我有一个由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;

您的选择是正确的。 您应该重写EXECUTE IMMEDIATE来执行

DROP TABLE EMP_DBA.MARKET_DATA

“我已授予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> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM