【问题标题】:how handle table or view does not exist exception?如何处理表或视图不存在异常?
【发布时间】:2013-05-24 09:30:34
【问题描述】:

我有一组表名,比如说 150。每个表都有 mail_id 列,现在我想在所有表中搜索一个 mail_id。为此,我写了一个 Plsql 块。当我遍历一组表时,某些表不存在,因此会引发异常。我有异常处理块来处理该异常。现在我想循环整个表,即使它引发异常?任何想法?实际上我的块没有处理那个特殊的异常!

declare
my_mail_id varchar2(50):='xyaksj@jsm.com';
tmp_table varchar2(125);
type varchar_collector is table of varchar2(255);
var varchar_collector;
table_does_not_exist exception;  
PRAGMA EXCEPTION_INIT(table_does_not_exist, -00942);

begin

for cntr in (select table_name from user_tables)
    loop

    tmp_table:=cntr.table_name;
    dbms_output.put_line(tmp_table);
        for mail in (select email_address from tmp_table where lower(email_address) like '%my_mail_id%' )
        loop
            dbms_output.put_line(tmp_table);
        end loop;
    end loop;

    exception 
    when no_data_found then 
        dbms_output.put_line('email address not found');

    WHEN table_does_not_exist then 
         dbms_output.put_line('table dose not exists');

    WHEN OTHERS THEN
    --raise_application_error(-20101, 'Expecting at least 1000 tables');
    IF (SQLCODE = -942) THEN
        --DBMS_Output.Put_Line (SQLERRM);
        DBMS_Output.Put_Line ('in exception');--this exception not handled
    ELSE
        RAISE;
    END IF;
end;

【问题讨论】:

    标签: sql exception plsql oracle11g


    【解决方案1】:

    只需在循环内的匿名块中处理您的异常。

    DECLARE
      my_mail_id VARCHAR2(50) := 'xyaksj@jsm.com';
      tmp_table  VARCHAR2(125);
      TYPE varchar_collector IS TABLE OF VARCHAR2(255);
      var varchar_collector;
      table_does_not_exist EXCEPTION;
      PRAGMA EXCEPTION_INIT(table_does_not_exist, -00942);
    
    BEGIN
    
      FOR cntr IN (SELECT table_name FROM user_tables)
      LOOP
        BEGIN
          tmp_table := cntr.table_name;
          dbms_output.put_line(tmp_table);
          FOR mail IN (SELECT email_address
                         FROM tmp_table
                        WHERE lower(email_address) LIKE '%my_mail_id%')
          LOOP
            dbms_output.put_line(tmp_table);
          END LOOP;
    
        EXCEPTION
          WHEN no_data_found THEN
            dbms_output.put_line('email address not found');
    
          WHEN table_does_not_exist THEN
            dbms_output.put_line('table dose not exists');
    
          WHEN OTHERS THEN
            --raise_application_error(-20101, 'Expecting at least 1000 tables');
            IF (SQLCODE = -942)
            THEN
              --DBMS_Output.Put_Line (SQLERRM);
              DBMS_Output.Put_Line('in exception'); --this exception not handled
            ELSE
              RAISE;
            END IF;
        END;
      END LOOP;
    END;
    

    【讨论】:

      【解决方案2】:

      如果您从 user_tables 中选择并发现其中一些不存在,那么您可能正在尝试查询回收站中的表(它们的名称以 BIN$ 开头)。

      如果是这样,请将您的查询更改为:

      select table_name
      from   user_tables
      where  dropped = 'NO';
      

      您也应该将第二个游标替换为执行立即调用,通过在 table_name 中连接来构造查询,而不仅仅是使用变量作为表名,您也可以将查询构造为:

      select count(*)
      from   table_name
      where  lower(email_address) like '%my_mail_id%'
      and    rownum = 1;
      

      这样您将检索一个 0 或 1 的记录,以指示是否找到了电子邮件地址,并且无需进行错误处理。

      【讨论】:

      • 不,伙计,这实际上不是 user_tables .....我只是说一个例子!!!它是其他一些表..
      • 这就是我们喜欢看实际代码的原因——所以我们不会把时间浪费在这样的事情上。然后我猜问题是您的查询说“从 tmp_table 中选择 email_address”,它实际上是在寻找一个名为 tmp_table 的表。您必须将查询构造为字符串文字并使用 execute immediate 执行它。
      • 你的意思是变量 tmp_table 在执行查询时不能替换它的值,对吧?
      • 正确 -- 该字符串被 PL/SQL 引擎识别为 SQL,并按原样传递给 SQL 引擎。
      【解决方案3】:
      try below code...
      
      DECLARE
         foo  BOOLEAN;
      BEGIN
         FOR i IN 1..10 LOOP
            IF foo THEN
               GOTO end_loop;
            END IF;
         <<end_loop>>  -- not allowed unless an executable statement follows
         NULL; -- add NULL statement to avoid error
         END LOOP;  -- raises an error without the previous NULL
      END;
      

      【讨论】:

      • 这如何回答 OP 的问题?
      • OP 想要抑制循环中的异常
      • 您的异常处理块到底在哪里?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-13
      • 2013-04-29
      • 1970-01-01
      • 1970-01-01
      • 2013-08-05
      • 1970-01-01
      相关资源
      最近更新 更多