2014-01-21 107 views
-2

我有两个表,
有人可以解释一下吗?

  • reorder_table(item_id number,stock_level number) and
  • stock(item_id number,item_desc varchar2(20),stock_level number)

enter image description here

根据该数据PENPENCIL应该需要重新排序因为他们的库存水平低于订货股票值。

我有一个日志表sql_errors记录需要重新排序的项目。这里是我的代码

DECLARE 
    out_of_stock EXCEPTION; 
    v_item  VARCHAR2(20); 
    CURSOR inv_cur 
    IS 
    SELECT a.item_id, 
     b.item_desc, 
     a.stock_level reorder_level, 
     b.stock_level stock_level 
    FROM reorder_level a, 
     stock b 
    WHERE a.item_id=b.item_id ; 
BEGIN 
    BEGIN -- sub block 
    FOR c IN inv_cur 
    LOOP 
     IF c.reorder_level > c.stock_level THEN 
     v_item :=c.item_desc; 
     raise out_of_stock; 
     END IF; 
    END LOOP; 
    EXCEPTION 
    WHEN out_of_stock THEN 
    INSERT INTO sql_errors VALUES 
     ('Item '||v_item|| ' Is out of Stock'); 
    END; -- sub block ends 
END; 

,以便继续执行引发异常后也并记录需要重新排序的所有项目我都写的内部块。但在日志表中只有项目PENCIL正在记录。不是笔。
为什么会发生这种情况?

回答

1

你可以看到一个RAISE将发送控制EXCEPTION块它是。和执行后,该块完成。在你的情况下,LOOP被写入子块本身,所以在Exception控制从第一个异常后的子块移开。

我已将您的子区块移动到LOOP之内,如下所示。

DECLARE 
    out_of_stock EXCEPTION; 
    v_item  VARCHAR2(20); 
    CURSOR inv_cur 
    IS 
    SELECT a.item_id, 
     b.item_desc, 
     a.stock_level reorder_level, 
     b.stock_level stock_level 
    FROM reorder_level a, 
     stock b 
    WHERE a.item_id=b.item_id ; 
BEGIN 
    FOR c IN inv_cur 
    LOOP 
    BEGIN -- sub block 
     IF c.reorder_level > c.stock_level THEN 
     v_item :=c.item_desc; 
     raise out_of_stock; /* goes to the exception block */ 
     END IF; 
    EXCEPTION 
    WHEN out_of_stock THEN 
     INSERT INTO sql_errors VALUES 
     ('Item '||v_item|| ' Is out of Stock'); 
    END; -- sub block ends 
    /* Loop Continues! */ 
    END LOOP; 
END; 
/
+0

谢谢!现在我清楚了 – redsoxlost

1

为什么在使用异常而不是在检测到某件商品缺货时只进行插入操作?

if c.reorder_level > c.stock_level then 

    v_item :=c.item_desc; 

    insert into sql_errors 
    values ('Item '||v_item|| ' Is out of Stock'); 

end if; 
+0

其实我试图了解如何继续执行,即使发生异常。在这种情况下,我试图记录该项目,并在发生异常时继续执行。 – redsoxlost

+2

根据http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/errors.htm#LNPLS00701,它看起来像控制无法返回到引发异常的点: 运行异常处理程序后,控制转移到封闭块的下一个语句。如果没有封闭块,则: 如果异常处理程序在子程序中,则控制权将在调用后的语句处返回到调用者。 如果异常处理程序位于匿名块中,则控制权转移到主机环境(例如,SQL * Plus) – Darren

0
insert into sql_errors 
    select 'Item '||b.item_desc|| ' Is out of Stock' 
    from reorder_level a, stock b 
    where a.item_id = b.item_id and a.stock_level > b.stock_level