PLSQL执行立即ORA-00955名称已被现有对象使用

时间:2018-07-25 16:34:06

标签: sql oracle plsql

我制作了一个PL / SQL块,如果不存在该表,则会创建一个表。如果存在,则它将截断该表。当我执行脚本时,出现以下错误:

ORA-00955 name is already used by an existing object

您能帮我解决此错误吗?

脚本

DECLARE
nCount NUMBER;
vSqlStatement LONG;
BEGIN
    SELECT count(1) into nCount FROM all_tables where table_name = 'CHANGES'; 
    IF(nCount <= 0)
    THEN
       dbms_output.put_line (' Greather or equal to 0: ' || nCount);     
       vSqlStatement:='
       CREATE TABLE ADMRAPPORT.CHANGES
       (
            "ID" NUMBER(10),
            "VersionName" VARCHAR2(255),
            "VersionNumber" NUMBER(10),
            "Version_ID" NUMBER(10),
            "VersionFlag" VARCHAR2(255)
        )';
      execute immediate vSqlStatement;    
    END IF;
    IF(nCount > 0)
    THEN
        dbms_output.put_line (' Smaller then 0');
        vSqlStatement:='TRUNCATE TABLE ADMRAPPORT.CHANGES';
        execute immediate vSqlStatement;
    END IF;
END;

3 个答案:

答案 0 :(得分:1)

如果可以以ADMRAPPORT用户身份运行脚本并删除对架构名称的引用,这一切都会简单得多。

当前,您检查ALL_TABLES是否有任何属于任何模式的名为CHANGES的表。 ALL_TABLES仅向您显示您有权访问的表,这意味着已授予您或您具有的角色的表。这有两种可能会出错的方式:

  1. 某些其他模式(不是ADMRAPPORT)具有名为CHANGES的表,并授予您对其的访问权限。您的计数结果将为1,因此您的代码将停止而不创建ADMRAPPORT.CHANGES

  2. ADMRAPPORT.CHANGES实际上确实存在,但未授予您,因此您的计数结果为0,因为该表未显示在ALL_TABLES中。然后代码继续执行并尝试创建它,但失败了。也许这就是这里发生的事情。

如果您可以以ADMRAPPORT用户的身份调用脚本,请尝试以下简化版本:

declare
    object_already_exists exception;
    pragma exception_init(object_already_exists, -955);

    vsqlstatement long :=
       'create table changes
       ( id            number(10)
       , versionname   varchar2(255)
       , versionnumber number(10)
       , version_id    number(10)
       , versionflag   varchar2(255) )';

begin
    execute immediate vsqlstatement;
    dbms_output.put_line('Table created');
exception
    when object_already_exists then
        execute immediate 'truncate table changes';
        dbms_output.put_line('Table truncated.');
end;

我还将添加一些约束(ID是主键吗?列是否应该是NOT NULL?等等),并还要考虑授予和同义词。

请注意,我已从您的列名中删除了双引号,因为稍后它们只会造成混乱和错误。

答案 1 :(得分:0)

尝试使用DBA_OBJECTS而不是ALL_TABLES。如果您无权访问此表,则必须按照William的建议处理异常

答案 2 :(得分:-1)

您是否正确复制/粘贴了脚本?例如,您有:

IF(nCount <= 0)
    THEN
       dbms_output.put_line (' Greather or equal to 0: ' || nCount);

及以后

IF(nCount > 0)
    THEN
        dbms_output.put_line (' Smaller then 0');