如何在 PL/SQL 中设计易于阅读的输入验证?

How to design easy to read input validation in PL/SQL?

我正在完全重写 PL/SQL 程序,该程序是第三方系统的 EBS 入站接口。在此过程中,我们从加载到 table 的第 3 方系统接收输入,程序循环通过 table 调用 EBS API 来修改和创建记录。业务逻辑非常复杂,代码已经失控,这是重写的原因。

在调用某些 EBS API 之前,我们需要根据 Oracle EBS 系统中的内容验证传入数据。当前代码有几个(20 多个)程序来检查各种传入数据。这些过程中的每一个 return 都是一个状态和一条消息。然后有一个调用所有这些验证程序的主程序,在每个程序调用之后它查看状态和消息 - 主程序基本上是一大堆 if-else 语句,遵循起来非常麻烦。

我想知道是否有更合适table 的做法来执行如此数量的验证,以便代码更易于阅读和维护。我考虑过将所有过程变成 return 布尔值的函数,但我仍然遇到主调用过程中大量 if-else 语句的问题。目前我只是在寻找其他想法,最终目标是提高这个程序的可维护性。

提前致谢

你无法逃避这样一个事实,即如果你有 20 个东西你必须评估,你需要以某种方式有 20 个检查点。

您的问题陈述非常广泛,但下面是我如何成功实施相同模式的一个示例。主要思想是检查(或验证)不会污染主要业务逻辑,而是清楚地分开,因此主要业务逻辑很容易遵循。 PL/SQL 有时是有点冗长的语言 - 这里的冗长进入异常处理。

请注意,在示例中我做了一些假设,这些假设可能不适用于您的具体情况。

验证包:

--
-- NOTE: PL/SQL look alike pseudo code - won't compile
--

-- br = business rule
create or replace package body so46_br is

  -- different exceptions required only if each case needs to be identified
  -- later in exception handling
  err_br_1 constant pls_integer := -20001;
  ex_br_1 exception;
  pragma exception_init(ex_br_1, -20001);
  -- ...
  err_br_20 constant pls_integer := -20020;
  ex_br_20 exception;
  pragma exception_init(ex_br_1, -20020);

  procedure assert_br_1(/* input params */) is
    v_fail boolean := false;
    v_msg varchar2(2000);
  begin
    -- validate the business rule #1

    if v_fail then
      v_msg := 'Construct detailed reason why the validation failed.';
      raise_application_error(err_br_1, v_msg, true);
    end if;
  end;

  -- ...

  procedure assert_br_20(/* input params */) is
    v_fail boolean := false;
    v_msg varchar2(2000);
  begin
    -- validate the business rule #20

    if v_fail then
      v_msg := 'Construct detailed reason why the validation failed.';
      raise_application_error(err_br_20, v_msg, true);
    end if;
  end;

end;

业务逻辑包:

--
-- NOTE: PL/SQL look alike pseudo code - won't compile
--

-- bl = business logic
create or replace package body so46_bl is

  procedure main(/* input params */) is
  begin
    -- #1 validate input params/business rules
    -- assumes we can quit if any validation fails

    so46_br.assert_br_1(/* input params */);
    -- ...
    so46_br.assert_br_20(/* input params */);

    -- #2 do the other business logic things
  exception
    -- assumes each validation failure needs to be identifiable
    when so46_br.ex_br_1 then
      so46_log.log_br_1(dbms_utility.format_error_stack ||
                        dbms_utility.format_error_backtrace);
      raise;
    -- ...
    when so46_br.ex_br_20 then
      so46_log.log_br_20(dbms_utility.format_error_stack ||
                         dbms_utility.format_error_backtrace);
      raise;
  end;

end;