关于pl / sql异常的问题 [英] question about pl/sql exception

查看:176
本文介绍了关于pl / sql异常的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下文本是oracle文档的摘录 Oracle®数据库PL / SQL语言参考11g第1版(11.1)

the following text is an excerpt of oracle documentation Oracle® Database PL/SQL Language Reference 11g Release 1 (11.1) :


未处理的异常也可以影响
子程序。如果您成功退出子程序
,则PL / SQL将值分配给
OUT参数。但是,如果您使用未处理的异常退出
,则PL / SQL
不会将值分配给OUT
参数(除非它们是NOCOPY
参数)。 另外,如果存储的
子程序失败并且未处理的
异常,则PL / SQL不会回滚子程序完成的
数据库工作。

Unhandled exceptions can also affect subprograms. If you exit a subprogram successfully, PL/SQL assigns values to OUT parameters. However, if you exit with an unhandled exception, PL/SQL does not assign values to OUT parameters (unless they are NOCOPY parameters). Also, if a stored subprogram fails with an unhandled exception, PL/SQL does not roll back database work done by the subprogram.

注意粗体文本,确实是这样吗?我很好奇,所以我写下面的例子来测试它。

note the bold text, does that true? i'm curious about that, so i wrote the following example to test it.

-- create a test table
CREATE TABLE e AS SELECT * FROM HR.EMPLOYEES;   

-- create p1 which will update a row in table e
CREATE OR REPLACE PROCEDURE p1
IS
    ex EXCEPTION;
    row e%ROWTYPE;
BEGIN
    select * into row from e where employee_id=100;

    row.employee_id := 100;
    row.first_name := 'yang';

    -- update
    UPDATE e set ROW = row where employee_id = 100;
    -- and raise an error
    RAISE ex;
END;


BEGIN
    -- call the upper procedure
    p1;
END;

-- test whether update success
select * from e where employee_id=100;

-- the upper query gives me
Steven

so我的问题是:我是对的吗?

so my question is: am i right?

推荐答案

请参阅这个问题: Oracle是否会在错误回滚事务?

在您的情况下,过程P1将成功或失败,并回滚其更改。为什么它看起来像文档中的声明相反(p1在程序中间失败并留下未完成的工作)?

In your case the procedure P1 will either succeed or fail and roll back its changes. Why does it look like the statement from the documentation states the opposite (p1 fails in the middle of the procedure and leaves unfinished work)?

答案在于在你的报价之前的句子


记住,如果它找不到一个引发的异常的处理程序,PL / SQL返回一个未处理的异常错误到主机环境,这决定了结果。例如,在Oracle预编译器环境中,由SQL失败的SQL语句或PL / SQL块所做的任何数据库更改都将回滚。

这意味着当一个程序失败时,如果未处理的引发的异常,则不完整的工作将被回滚。但是,如果异常被捕获并且不被重新提供,则不完整的工作将被保留。

What this means it that when a procedure fails, if the raised exception is unhandled, the incomplete work will be rolled back. However, if the exception is catched and not re-raised the incomplete work will be left as is.

我们可以通过将WHEN OTHERS块(而不是重新提出例外 - 当然这是一个真的很糟糕的主意,请看下面为什么)在你的例子中:

We can show this behaviour by putting a WHEN OTHERS block (and not re-raising an exception -- of course it's a really really bad idea see below why) in your example:

SQL> BEGIN
  2     -- call the upper procedure
  3     p1;
  4  EXCEPTION
  5     WHEN OTHERS THEN
  6        dbms_output.put_line('log error...');
  7  END;
  8  /

log error...

PL/SQL procedure successfully completed

SQL> select employee_id, first_name from e where employee_id = 100;

EMPLOYEE_ID FIRST_NAME
----------- --------------------
        100 yang

你真的 永不想要 这样做 :我们离开了未完成的工作,错误被记录并且通过不重新提高它,我们有一个潜在的严重错误。此外,默默地忽略例外是灾难的秘诀。

You really never want to do this: we left unfinished work, the error is logged and by not re-raising it we have a potentially serious bug. Furthermore, silently ignoring exceptions is a recipe for disasters.

这篇关于关于pl / sql异常的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆