Pl/SQL 嵌套过程异常处理

2023-12-29

这是关于通过多个级别的 PL/SQL 过程进行错误处理的最佳实践问题。我查看了其他一些问题来帮助我解决问题,特别是this one https://stackoverflow.com/questions/7360565/pl-sql-exception-handling-in-procedures.

目前,我有一个包含过程 1 的程序,它调用过程 2,过程 2 又调用过程 3。我正在尝试执行足够的错误处理 - 但我想最终将确切的问题输出回应用程序层。我希望得到一些关于如何有效、清晰地做到这一点的想法。

我当前的解决方法如下,但对我来说似乎相当混乱,有很多变量声明。我对 PL/SQL(以及一般的 SQL)非常陌生,所以我希望得到以下方面的建议:

  1. 处理多层程序时良好的错误处理技术。
  2. 将错误消息反馈到应用程序层(在下面的过程中,由“out_overall_output”变量表示)。

程序流程:UI -> Proc 1 -> Proc 2 -> Proc 3

程序1:

--One input variable, one output.
in_id                VARCHAR2;
out_overall_output   VARCHAR2;
...
DECLARE
    l_success         BOOLEAN;
    l_error_output    VARCHAR2(100);
BEGIN
    Proc2(id, l_success, l_error_output);
    IF l_success = FALSE THEN
        out_overall_output = l_error_output
    END IF
EXCEPTION
WHEN OTHERS THEN
    ROLLBACK;
    out_overall_output:= 'Error calling Proc 2'
    RETURN;
END;
--Normal flow continues if l_success is true...

程序2:

-- One input variable, two output.
in_id
out_success
out_error_output
//other logic
DECLARE
    l_success         BOOLEAN;
    l_error_output    VARCHAR2(100)
BEGIN
    Proc3(id, l_success, l_error_output)
    IF l_success = FALSE THEN
        out_error_output = l_error_output
    END IF
EXCEPTION
WHEN OTHERS
    out_error_output = 'Error calling Proc 3'
    RETURN;
END;

程序3:

--One input variable, two output.
in_id                VARCHAR2;
out_success          BOOLEAN;
out_error_message    VARCHAR2;
...
BEGIN
    DELETE 
    FROM table
    WHERE id = in_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
    out_success = FALSE;
    out_error_message = 'Error - No data to delete'
WHEN OTHERS THEN
    out_success = FALSE;
    out_error_message = 'Error deleting data.'
END;

注意:过程调用的层次比这更深。我所展示的片段已大大简化。我的真实程序中的错误消息和变量名称更具描述性。


要显示应用程序级别的“服务器发生的情况”的确切解释,您可以尝试以下操作。在程序上:

create or replace procedure p1 is
...
exception
  when <some_error> then
    <do something>
    -- re-raise error:
    raise_application_error(-20001, 'Client with ID '|| ID || ' has no right to perform action "' || ACTION_NAME || '"', true);
end;

create or replace procedure p2 is
begin
  p1;
exception
  when <another_error> then
    <do something>
    -- re-raise error:
    raise_application_error(-20002, 'Action "' || ACTION_NAME || '" is not completed', true);
end;

create or replace procedure p3 is
begin
  p2;
exception
  when <another_error> then
    <do something>
    -- re-raise error:
    raise_application_error(-20003, 'Purchasing of "' || CAR_NAME || '" cancelled', true);
end;

在顶层程序中:

create or replace procedure top_level_procedure is
begin
  p1;
exception
  when <one_more_error> then
    <do something>
    raise_application_error(-20004, dbms_utility.format_error_backtrace);
end;

异常后p1你会看到这样的东西:

ORA-20003: Purchasing of "Cool red Ferrari" cancelled
ORA-20002: Action "car purchase" is not completed
ORA-20001: Client with ID 123 has no right to perform action "Spent all money of Bill Gates"

程序的第三个参数raise_application_error with false值会删除所有先前的错误消息。如果您将在程序中使用错误值p3,您只会看到一条带有代码的错误消息ORA-20003在这个例子中。

P.S.您也可以定义自己的异常并在中使用它们WHEN .. THEN条款。您可以在这里找到更多信息和示例:https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/errors.htm#LNPLS00704 https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/errors.htm#LNPLS00704

P.P.S. 如何登录。日志程序:

create or replace procedure log(p_log_message varchar2) is
pragma autonomous_transaction;
begin
  insert into log_table(..., log_message) values (..., p_log_message);
  commit;
end;

通话记录流程:

  when <one_more_error> then
    <do something>
    log(..., dbms_utility.format_error_backtrace);
    raise_application_error(-20004, dbms_utility.format_error_backtrace);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pl/SQL 嵌套过程异常处理 的相关文章

随机推荐

  • MySQL按出现次数排序

    我正在两个名为的文本字段中进行搜索Subject and Text对于特定的关键字 为此 我使用LIKE陈述 我在尝试按出现次数对结果进行排序时遇到了问题 我的搜索查询如下所示 SELECT FROM Table WHERE Text LI
  • 在 Gnuplot 中,如何在第三列等于 0 时使点为一种颜色,否则为另一种颜色?

    我需要根据一列中的颜色改变一行值的点颜色 数据 x y z 1 3 0 1 5 6 3 5 2 4 5 0 如果该列为零 则颜色应为一个值 如果第三列中的值非零 则颜色应为不同的颜色 所以 我假设 plot file dat u 1 2 3
  • 在 Linux 中删除文件名中的空格[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我在不同的文件夹中有数百个 jpg 文件 如下所示 304775 105 01 jpg 304775 105 03 jpg 304775 105 05
  • DUAL 的魔力

    正常情况下 不使用SYS或者也许使用它 SQL gt select from dual D X 在不太正常的条件下 连接为SYS SQL gt alter database close Statement processed SQL gt
  • WPF 树视图蓝调。我想选择一个项目

    我正在尝试选择一个 TreeViewItem 现在 我可以访问包含的 TreeViewItem 并告诉它展开 以便我可以选择它的孩子 如果它已经展开 一切都很好 如果没有 那么我运行以下代码 EventHandler selector ne
  • MYSQL LEFT JOIN 与 CASE 优化

    我花了一些时间尝试使用 CASE 来处理这个 SELECT 但我失败了 感谢我现在正在使用 COLASCE 如何使用 CASE IF 语句优化此 SELECT 这是从字段选择的不同表中查询的快速方法吗 SELECT a folderid a
  • 将 Eclipse 从 Indigo 升级到 Juno 时我可以保留我的设置吗?

    如何将 Eclipse 从 Indigo 升级到 Juno 而不会丢失所有自定义设置 我尝试了两种不同的方法 但都不起作用 从 Indigo 导出首选项并导入 Juno 在 Indigo 工作区的副本上运行 Juno 每次升级都得从头开始真
  • .Net:如何创建独立于供应商的数据集、表适配器、绑定(数据库在运行时决定)

    我有一个 C Windows 窗体应用程序 其原型是在 SQL Server 强类型数据集 上创建的 在其最终版本中 应用程序必须能够在 SQL Server MySQL 或 Oracle 上运行 现在我想知道原型中的哪些部分 如果有 可以
  • MongoDB 5.0+ 需要支持 AVX 的 CPU。容器启动失败

    我正在尝试使用 docker compose 文件在 docker 容器中运行 mongo 6 但它总是退出并出现警告 Docker 版本 23 0 4 内部版本 f480fb1 Docker compose版本 v2 17 2 docke
  • 预渲染不会保留用于捕获第二遍的变量值

    我查看了有关如何预渲染 Blazor 服务器应用程序然后分两次渲染的各种文章 我已经审查了生命周期 并且非常清楚这是预期的行为 主要是为了提供良好的性能 我不想关闭预渲染 所以在加载数据结构和类似的东西时我必须考虑它 我需要能够运行与数据库
  • PHP 中的优先运算符“OR”和“=”

    a 1 a OR a somthing echo a 1 Why If 比 OR 优先得多 那么为什么 OR 先执行呢 当您在两个语句之间放置 OR 时 如果第一个语句返回 true 则第二个语句永远不会被执行 在这种情况下 第一个语句 a
  • 使用 Nashorn JavaScript 引擎访问 ScriptContext 变量 (Java 8)

    我使用了以下代码RhinoJava 中的 JavaScript 引擎 Test public void testRhino throws ScriptException final ScriptEngineManager factory n
  • 仅使用 HTML/CSS 创建粗箭头

    有没有办法仅使用 html 和 css 创建 4 个指向上 下 左 右的粗箭头 使用 s 和边框创建箭头的主干非常容易 这是箭头头的对角线 我不知道该怎么做 我需要它在 IE7 和所有现代浏览器中工作 我使用 jQuery 并且很高兴依赖它
  • 包含关键字的 Linq 不同记录

    我需要根据汽车关键字搜索返回不同的记录列表 例如 Alfa 147 问题是 由于我有 3 辆 Alfa 汽车 它返回 1 3 条记录 似乎 1 表示 Alfa 和 147 结果 3 表示 Alfa 结果 EDIT SQL Server 查询
  • gitolite 后接收挂钩未触发

    In my gitolite rc我有的文件 LOCAL CODE gt ENV HOME gitolite local 然后在ENABLE我已启用的同一文件的部分repo specific hooks ENABLE gt COMMANDS
  • 将录制的 Twilio 音频发送到 Lex

    目前我可以录制用户输入 将录制 URL 传递给所需的函数 并在本地下载音频文件 我试图对音频文件执行的操作是获取音频文件的缓冲区以发送到 Lex 或者将其转换为 Lex 需要的格式 根据 AWS 文档 输入流参数值接受以下值 var par
  • Java:网络设置窗口

    我正在寻找一种方法来对带有点的文本字段进行编程 例如 Windows 网络设置对话框中的点 参见 gt gt https i stack imgur com gayeY jpg https i stack imgur com gayeY j
  • PrimeFaces 的惰性数据模型加载方法未调用

    我碰巧不明白为什么我的加载方法没有在我的 primefaces 表的惰性数据模型中调用 我的 xhtml 页面是这样的
  • Heroku:当我执行“heroku run console”时,我需要付费吗?

    我分别运行了三个命令 bash console and node 当我做heroku ps我明白了 heroku ps Process State Command run 1 complete for 11m console run 2 c
  • Pl/SQL 嵌套过程异常处理

    这是关于通过多个级别的 PL SQL 过程进行错误处理的最佳实践问题 我查看了其他一些问题来帮助我解决问题 特别是this one https stackoverflow com questions 7360565 pl sql excep