Plsql 匿名PL/SQL块检查异常

Plsql 匿名PL/SQL块检查异常,plsql,exception-handling,oracle11g,Plsql,Exception Handling,Oracle11g,我试图捕获匿名PL/SQL块中的异常 DECLARE ... BEGIN FOR herstell_row IN ( ... ) LOOP ... DECLARE table_does_not_exists exception; pragma exception_init( table_does_not_exists, -942 ); BEGIN INSERT INTO SMART_MONITORING

我试图捕获匿名PL/SQL块中的异常

DECLARE
    ...

BEGIN
FOR herstell_row IN (
    ...
) 
LOOP
    ...

    DECLARE
        table_does_not_exists exception;
        pragma exception_init( table_does_not_exists, -942 );
    BEGIN
        INSERT INTO SMART_MONITORING_MACHINE_NAV_B (
            MACHINE, 
            NAVIGATION_LEVEL_ID
        ) 
        SELECT 
            old_binding.MACHINE, 
            pv_id 
        FROM 
            SMART_MACHINE_NAV_BINDING old_binding
        WHERE
            old_binding.NAVIGATION_LEVEL_ID = herstell_row.HENAME1;
    EXCEPTION
        WHEN table_does_not_exists THEN null;
    END;

END LOOP;
END;
我知道在我的例子中不存在表SMART\u MACHINE\u NAV\u绑定,所以我需要嵌套的匿名块来忽略它的代码。但我总是犯这样的错误:

错误报告- ORA-06550:第41行第14列: PL/SQL:ORA-00942:表或视图不存在 ORA-06550:第33行第10列: PL/SQL:SQL语句被忽略


Oracle不知道这个错误表存在,因为它是用户定义的,所以您应该在其他人出现时处理它,例如

Exception
  When Others then
     null;
  -- or at this time you can raise your error table_does_not_exists
    raise table_does_not_exists;
  -- and handle it in another parent block
end;
Exception
   when table_does_not_exists then
     null;
end;

不能使用不存在的表编译代码,但可以尝试使用
executeemmediate

DECLARE
    ...

BEGIN
FOR herstell_row IN (
    ...
) 
LOOP
    ...

    DECLARE
        table_does_not_exists exception;
        pragma exception_init( table_does_not_exists, -942 );
    BEGIN
      execute immediate 
        'INSERT INTO SMART_MONITORING_MACHINE_NAV_B (
            MACHINE, 
            NAVIGATION_LEVEL_ID
        ) 
        SELECT 
            old_binding.MACHINE, 
            pv_id 
        FROM 
            SMART_MACHINE_NAV_BINDING old_binding
        WHERE
            old_binding.NAVIGATION_LEVEL_ID = :P' using herstell_row.HENAME1;
    EXCEPTION
        WHEN table_does_not_exists THEN null;
    END;

END LOOP;
END;
此外,此处不需要异常,您可以使用系统视图检查表的存在性:

declare
  table_created number;
begin
  select count(*)
    into table_created
    from all_tables
   where table_name = ...
     and owner = ...;

  if table_created > 0 then
     execute immediate 'insert into ...';
  end if;
end;

有关
executeimmediate
语句的更多信息:

Typo:您在
表中有一个额外的
s
\u不存在*s*
您在代码中使用的所有数据库对象都必须在运行时存在,否则您将得到这样的错误。为什么要从不存在的表中进行选择?@Dmitry这是一个迁移脚本。它在部署新的应用程序版本时执行。有些系统有此表,有些系统没有。