在RPG中覆盖。

Override in RPG.

我有一个条件。 我有一个 CL,我在其中用 Qtemp 版本 (QTEMP/TabA) 覆盖 table(TabA)。然后我调用一个 RPG 程序。 现在在 RPG 程序中,我对 TabA 进行更新。所以 Qtemp 版本正在更新,但我希望更新实际版本。所以基本上,就在这个更新中,我不希望我的覆盖起作用。一种方法是删除覆盖,然后在更新后将其覆盖回来。有没有更好的办法?

我不会在不同级别使用覆盖范围,而是通过在您的 F-spec 或 SQL 中使用完全限定的文件名来处理这种情况,并且根本不使用覆盖。听起来 RPG 程序应该总是更新永久文件,而不是临时文件,所以在 F-spec 上你可以使用关键字 EXTFILE(LIBNAME/FILENAME)。类似地,如果您使用 SQL,您可以将 table 称为 LIBNAME.FILENAME

我也会在 CL 程序中使用显式限定,参考 QTEMP/FILENAME 以便您可以完全删除覆盖。正如 Barbara Morris 指出的那样,如果您在范围内有覆盖,EXTFILE 关键字将指向覆盖文件,即使库名称是限定的。

覆盖有一些不错的功能,尤其是对于打印机文件,但听起来它们并不适合您。实际上,您有两个逻辑上独立的问题:对临时文件进行处理并对永久文件进行处理。他们应该单独对待。当您希望将对一个对象的 所有 引用替换为对另一个对象的引用时,覆盖是一种更好的技术。

另一种解决方案是在 table.

上简单地创建一个 LF(或 Index 或 View )

为逻辑添加 F-spec 并让您的更新使用该 LF。

无论覆盖是否到位,实际的 PF 都会更新。

另一种选择是将RPG 程序放在与CL 不同的激活组中。尽管如果您在覆盖上设置了 OVRSCOPE(*JOB),那将不起作用。

显而易见的解决方案是让 CL 和 RPG 单独存在,并且 OVRDBF TABA TOFILE(production_library/TABA) 呼叫 the_cl_program

之所以可行,是因为它覆盖了从外到内的工作。 OVRSCOPE、激活组等都增加了使它成为在所有情况下都推荐的解决方案的复杂性。

假设您已经得出该结论,下一个明显的解决方案是简单地 运行 RPG 程序 'naked' - 在 CLP 之外。我可以假设,如果那是可行的,你就已经做到了。也许有问题的 CL 位于由更大进程调用的一整串其他 CL 中。

下一个显而易见的解决方案是更改 CLP;取出OVRDBF,运行大进程,再放回去。这行得通,但存在必须记住两次编译生产程序、设置权限等问题。在我这样做之前,我会考虑对该 CLP 进行稍微不同的更改。根据您的需要,使用开关打开或关闭 OVRDBF。

像这样的改变需要发生一次是非常罕见的。可能有问题,大进程需要重新运行,只有这一个程序需要更新生产,而不是QTEMP。考虑使用外部指示器——类似于 if %switch(xxxxxxx1) then (OVRDBF...)。如果这些开关已被使用,请考虑制作一个您可以检索和测试的数据区域。

如果所有这些听起来工作量太大,那么我的后备方案是重新 运行ning Big Processed 失败了。我的黄金法则是永远不要更改经过测试的 运行ning 生产代码。制作一次性 're-run' 版本。 1) 复制big_process_cl。称它为 big_process_rerun 或类似的名称。 2) 复制the_clp_with_ovrdbf。同样的想法。 3) 更改并编译 big_process_cl_re运行 以调用您需要的所有内容,但是当它尝试调用 clp_with_ovrdbf 时,将该行更改为 CALL clp_with_ovrdbf_re运行. 4) 将 clp_with_ovrdbf 更改为没有 OVRDBF。 5) 编译 2 xxx_rerun CL 6) 呼叫 big_process_cl_re运行

这看起来工作量很大,但只有 2 个 CL,而且您永远不会 touched/broken 生产代码。同样,这对于解决 运行 类问题非常有用,但它可能不符合您的需求。

导致此要求的业务问题是什么?

编辑: 显然,PGMA 读取了一个非常大的文件中的所有行,但只需要处理一个子集。当它读取记录时,它也会更新它们。将输入重定向到必要的子集的想法是一个好主意,但这意味着生产 table 没有得到它的更新。如果我有这些限制(不得更改 PGMA),我会再编写一个程序。在 PGMA 运行 秒并更新 QTEMP/TABA 之后,这个新程序将读取 QTEMP/TABA 并将更改传播到生产环境。

在我看来,您的 TABA 程序中似乎只有一个 F 规范。如果是这种情况,您不能在不修改程序的情况下更改观察到的行为,但是可以通过创建新的逻辑和子过程来限制您的修改范围:

dcl-proc UpdateTABA;
  dcl-pi *n Ind;
    record       LikeRec(TABAREC:*output) const;
  end-pi;

  dcl-f tabanewlf    disk keyed usage(*update);

  chain (key) tabanewlf
  if %found(tabanewlf);
    update tabanewlf record;
    return *On;
  endif;
  return *Off;
end-proc;

那么只要有更新操作码,就可以调用这个子过程。由于它使用不同的文件名,因此不会受到覆盖的影响。

鉴于您正在使用 SQL,您还可以创建别名并更新它。别名不受覆盖的影响。它看起来像这样:

create alias qtemp/taba_alias for taba;

我刚刚在存在将文件覆盖为不同库中的空副本的覆盖的情况下对此进行了测试。

select * from taba;

returns 空数据集 while :

select * from taba_alias;

returns 具有预期数据的数据集。然后在完成后删除您的别名。请注意,我在 QTEMP 中创建了别名。这样多个用户就可以 运行 您的程序而无需重新创建或删除彼此的别名。

因此,如果您不介意那里有额外的工件,请使用视图;如果您只想创建一个指针,请使用别名。

谢谢大家。 我在创建别名并更新它而不是程序中的 TabA 后解决了这个问题。这非常有效,我也不想创建索引。