我有一个条件。我有一个CL,我用Qtemp版本(Qtemp/TabA)覆盖一个表(TabA)。然后我调用RPG程序。现在在RPG程序中,我对TabA进行了更新。因此,Qtemp版本正在更新,但我希望实际版本能够更新。所以基本上,就在这次更新中,我不希望我的覆盖工作。一种方法是删除覆盖,然后在更新后重新覆盖。有更好的方法吗?
另一种解决方案是简单地在表上创建一个LF(或Index或View)。
为逻辑添加一个F规范,并让您的UPDATE使用该LF。
不管覆盖是否到位,实际PF都将更新。
对我来说,这听起来就像你的程序中有一个用于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;
返回一个空数据集,同时:
select * from taba_alias;
返回包含预期数据的数据集。然后,当你完成你的别名时,把它放下。注意,我在QTEMP中创建了这个别名。这样,多个用户可以运行您的程序,而无需重新创建或删除彼此的别名。
因此,如果您不介意额外的工件,请使用视图;如果您只想创建一个指针,请使用别名。
显而易见的解决方案是不使用CL和RPGOVRDBF TABA TOFILE(生产库/TBA)调用_程序
这是因为覆盖是从外部向内部工作的。OVRSCOPE、激活组等都增加了在任何情况下都要推荐的解决方案的复杂性。
假设您已经得出了这个结论,那么下一个显而易见的解决方案就是在CLP之外"裸着"运行RPG程序。我可以假设,如果这是可行的,你就会这么做。也许有问题的CL是在一个更大的进程调用的一整串其他CL中。
下一个显而易见的解决方案是改变CLP;取出OVRDBF,运行大流程,然后将其放回原处。这是可行的,但有一个问题,那就是必须记住编译两次生产程序,设置权限等。在我这样做之前,我会考虑对CLP进行一个稍微不同的修改。根据您的需要,使用开关打开或关闭OVRDBF。
像这样的变化需要发生一次,这是非常罕见的。也许有问题,大流程需要重新运行,只有这一个程序需要更新生产,而不是QTEMP。考虑使用外部指示器,比如如果%switch(xxxxxxx 1),那么(OVRDBF…)。如果开关已经使用,考虑创建一个可以检索和测试的数据区域。
如果所有这些听起来都太工作量了,那么我重新运行Big Processed的失败就在于此。我的黄金法则是永远不要更改经过测试、正在运行的生产代码。制作一次性的"重新运行"版本。1) 制作big_process_cl的副本。称之为big_process_rerun或类似的东西。2) 使用_ovrdbf复制_clp_with_ovrdbf。同样的想法。3) 更改并编译big_process_cl_run以调用所需的所有内容,但当它尝试调用clp_with_ovrdbf时,请将该行更改为call clp_with_ovrdbf_rerun。4) 将clp_with_ovrdbf更改为不具有ovrdbf。5) 编译2个xxx_rerun CL6) 调用big_process_cl_重新运行
这看起来工作量很大,但只有2个CL,您永远不会接触/破坏生产代码。同样,这对于重新运行的问题很好,但可能不符合您的需求。
导致此要求的业务问题是什么?
编辑:显然,PGMA读取一个非常大的文件中的所有行,但只需要处理一个子集。当它读取记录时,它也会更新它们。将输入重定向到必要子集的想法很好,但这意味着生产表不会得到更新。如果我有这些限制(不能改变PGMA),我会再写一个程序。PGMA运行并更新QTEMP/TBA后,此新程序将读取QTEMP/TAB并将更改传播到生产中。
另一个选项是将RPG程序放在与CL不同的激活组中。尽管如果覆盖上有OVRSCOPE(*JOB),这将不起作用。
我不使用不同级别的覆盖,而是通过在F-spec或SQL中使用完全限定的文件名来处理这种情况,并且根本不使用覆盖。听起来RPG程序应该总是更新永久文件,而不是临时文件,所以在F规范中可以使用关键字EXTFILE(LIBNAME/FILENAME)
。类似地,如果您使用SQL,则可以将该表称为LIBNAME.FILENAME
。
我也会在CL程序中使用明确的限定,参考QTEMP/FILENAME
,这样您就可以完全删除覆盖。正如Barbara Morris所指出的,如果您在作用域中有覆盖,即使库名称是限定的,EXTFILE
关键字也会指向覆盖文件。
覆盖有一些不错的功能,尤其是对于打印机文件,但听起来它们不适合您。实际上,您有两个逻辑上独立的关注点:对临时文件进行处理和对永久文件进行处理。他们应该分开对待。当您希望对一个对象的所有引用都被替换为对另一对象的引用时,重写是一种更好的技术。
谢谢大家。我在创建Alias并更新它(而不是程序中的TabA)后解决了这个问题。这非常有效,我不想创建索引。