PL / SQL异常处理

时间:2016-01-22 07:11:29

标签: oracle plsql error-handling exception-handling

我是pl / sql编程的新手,并且一直试图从过去2小时开始解决这个问题

这是我的代码

CREATE OR REPLACE PROCEDURE xx_upd_new_code AS   

  CURSOR c1 IS
    SELECT
      eite.t_ep_item_ep_id,
      bite.main_item
    FROM bidw.item@demantra bite,
      t_ep_item eite
    WHERE bite.item_code = eite.item
          AND bite.main_item = bite.old_code
          AND bite.current_flag = 1
          AND bite.main_item IS NOT NULL;

  a1 c1%ROWTYPE;

  BEGIN
    xx_dbex('Starts.', 'xx_upd_new_code', 'XX');

    OPEN c1;
    LOOP
      FETCH c1 INTO a1;
      EXIT WHEN c1%NOTFOUND;

      xx_dbex('Item: ' || a1.main_item, 'xx_upd_new_code', 'XX');

      UPDATE t_ep_item
      SET item = a1.main_item
      WHERE t_ep_item_ep_id = a1.t_ep_item_ep_id;

      COMMIT;

      xx_dbex('Ends.', 'xx_upd_new_code', 'XX');
    END LOOP;

    EXCEPTION 
    WHEN OTHERS THEN xx_dbex('Error.', 'xx_upd_new_code', 'XX');   
  END xx_upd_new_code;

每当它收到错误时,程序结束,但我希望它移动到下一个项目。 xx_debex是存储日志的过程。

我一直在谷歌搜索,我发现我可以写两个例外&如果不满足条件,可以引发异常。我试过这个,但它会抛出一个错误 必须声明标识符a 标识符项必须声明

CREATE OR REPLACE PROCEDURE xx_upd_new_code AS   

  CURSOR c1 IS
    SELECT
      eite.t_ep_item_ep_id,
      bite.main_item
    FROM bidw.item@demantra bite,
      t_ep_item eite,
      items ite
    WHERE bite.item_code = eite.item
          AND bite.main_item = bite.old_code
          AND bite.current_flag = 1              
          AND bite.main_item IS NOT NULL;

  a1 c1%ROWTYPE;

  BEGIN
    xx_dbex('Starts.', 'xx_upd_new_code', 'XX');

    OPEN c1;
    LOOP
      FETCH c1 INTO a1;
      EXIT WHEN c1%NOTFOUND;

      IF item != a1.main_item THEN
        xx_dbex('Item: ' || a1.main_item, 'xx_upd_new_code', 'XX');

        UPDATE t_ep_item
        SET item = a1.main_item
        WHERE t_ep_item_ep_id = a1.t_ep_item_ep_id;
        COMMIT;

        xx_dbex('Ends.', 'xx_upd_new_code', 'XX');          
      ELSE
        RAISE a;
      END IF;

    END LOOP;

    EXCEPTION 
      WHEN a THEN xx_dbex('Error.', 'xx_upd_new_code', 'XX');
      WHEN OTHERS THEN NULL;   
  END xx_upd_new_code;

此外,它写的地方我可以用两个不同的块来写它

CREATE OR REPLACE PROCEDURE xx_upd_new_code AS

  CURSOR c1 IS
    SELECT
      eite.t_ep_item_ep_id,
      bite.main_item
    FROM bidw.item@demantra bite,
      t_ep_item eite
    WHERE bite.item_code = eite.item
          AND bite.main_item = bite.old_code
          AND bite.current_flag = 1
          AND bite.main_item IS NOT NULL;

  a1 c1%ROWTYPE;

  BEGIN
    xx_dbex('Starts.', 'xx_upd_new_code', 'XX');

    BEGIN

      EXCEPTION
      WHEN OTHERS THEN xx_dbex('Error', 'xx_upd_new_code', 'XX');
    END;

    OPEN c1;
    LOOP
      FETCH c1 INTO a1;
      EXIT WHEN c1%NOTFOUND;

      xx_dbex('Item: ' || a1.main_item, 'xx_upd_new_code', 'XX');
      UPDATE t_ep_item
      SET item = a1.main_item
      WHERE t_ep_item_ep_id = a1.t_ep_item_ep_id;
      COMMIT;

    END LOOP;

    EXCEPTION WHEN OTHERS THEN
    xx_dbex('END', 'xx_upd_new_code', 'XX'); 
  END xx_upd_new_code;

我仍然无法弄明白。

2 个答案:

答案 0 :(得分:1)

将光标循环分成两部分/块。第一个将用于调用日志记录过程的部分,另一个用于更新表的部分。您的代码正文应如下所示:

  BEGIN
     Open C1; 
     loop
        fetch C1 into A1;
        exit when C1%NOTFOUND
        BEGIN
           xx_dbex('Item: '||a1.main_item ,'xx_upd_new_code', 'XX');
        END;
        BEGIN
           UPDATE t_ep_item 
           SET item = a1.main_item
           where t_ep_item_ep_id=a1.t_ep_item_ep_id;
           COMMIT;
           xx_dbex('Ends.','xx_upd_new_code', 'XX');
        EXCEPTION
           WHEN OTHERS THEN 
              xx_dbex('Ends.','ERROR', 'XX');
        END;
  END LOOP;

希望你明白这个想法

答案 1 :(得分:0)

只需将循环中的语句放入一个新的pl / sql块中,如下所示:

loop
 begin
  fetch ...
 exception
  when ...
 end;
end loop;

顺便说一下。日志记录过程应使用pragma_autonomous_transactioncommit独立于当前事务结果。