代码之家  ›  专栏  ›  技术社区  ›  Erik hoeven

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

  •  0
  • Erik hoeven  · 技术社区  · 6 年前

    我已经制作了一个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 回复  |  直到 6 年前
        1
  •  1
  •   William Robertson    6 年前

    如果可以将脚本作为 ADMRAPPORT 用户并删除对架构名称的引用。

    目前您正在检查 ALL_TABLES 对于任何名为 CHANGES 属于任何模式的。 所有的桌子 只显示您有权访问的表,这意味着已授予您或您所具有的角色的表。有两种可能出错的方式:

    1. 其他模式(不是 广告 )有一个名为 变化 并允许您访问它。您的计数结果将为1,因此您的代码将停止而不创建 ADMRAPPORT.CHANGES .

    2. ADMRAPPORT.更改 事实上是存在的,但它不是授予您的,所以您的计数结果是0,因为表没有显示在 所有的桌子 . 然后代码继续并尝试创建它,但失败了。也许这就是这里发生的事。

    如果您可以将脚本称为 广告 用户,请尝试此简化版本:

    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;
    

    我还将添加一些约束(is ID 主键?任何列都应该是 NOT NULL ? 等),并考虑赠款和同义词。

    注意,我已经从列名中删除了双引号,因为这些只是在以后创建混乱和错误。

        2
  •  0
  •   Devendra K    6 年前

    尝试使用DBA_对象而不是所有的表。如果您没有访问此表的权限,则必须按照William的建议处理异常

        3
  •  -1
  •   tbone    6 年前

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

    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');