如何编写一个过程来测试对象是否存在并删除它?

时间:2016-02-18 08:06:03

标签: oracle database-schema

在Oracle中我试图创建PROCEDURE以删除任何命名对象(如果存在)。我想执行此查询select * from dba_objects where owner = 'TEST'。但是当我创建程序时,我得到错误: -

 create or replace PROCEDURE DROPDATABASEOBJECT11(ObjName varchar2,ObjType varchar2,schemaName varchar2)
-----PROCEDURE FOR DROP ALL DATABASE OBJECTS-----
IS
 v_counter number := 0;   
begin    
  if ObjType = 'TABLE' then
    select count(*) into v_counter select * from dba_objects where object_name = upper(ObjName);
    if v_counter > 0 then          
      execute immediate 'drop table ' || ObjName || ' cascade constraints';        
    end if;   
  end if;
  end;

我收到错误: -

Error(8,5): PL/SQL: SQL Statement ignored
Error(8,41): PL/SQL: ORA-00942: table or view does not exist

那么如何在程序中使用该查询呢?

1 个答案:

答案 0 :(得分:2)

我怀疑问题是访问DBA_OBJECTS。普通用户没有DBA视图的权限。即使他们确实可以访问DBA视图,但它通常是通过一个角色来实现的,而且我们无法针对通过角色授予的依赖对象构建PL / SQL程序(或视图)。

解决方案是:

  1. 改为使用ALL_OBJECTS
  2. 直接向您的用户授予DBA_OBJECTS授权用户(DBA)授予权限。
  3. 另一个潜在的问题是您没有使用架构命名空间限制查询和动态SQL。所以,你的代码应该是这样的:

    select count(*) into v_counter
    from dba_objects 
    where object_type = ObjType
    and owner = upper(SchemaName)
    and object_name = upper(ObjName);
    
    if v_counter > 0 then          
      execute immediate 'drop table ' || SchemaName || '.' || ObjName
                || ' cascade constraints';        
    end if;