如何像平常一样阅读源文件 PF/LF

How to read Source files like normal PF/LF

我目前正在开发一个将物理文件从生产环境传输到我的测试环境的程序。为此,我想

A co-worker 告诉我使用 CL 和 OVRDBF QRPGSRC,在我的 F-Specs 中定义 QRPGSRC 并像其他所有 PF 一样使用它们(READ/CHAIN成员名字)。这看起来有点乱,所以我搜索了另一个解决方案:在 F-Specs: https://www.google.de/search?q=ibm+rpg+EXTMBR

中使用 keyworks

所以我在 TSTLIB 中用 CRTSRCPF 创建了 4 个 PF-SRC:

CRTLIB LIB(TSTLIB) TYPE(TEST)
CRTSRCPF FILE(TSTLIB/QCLSRC)
CRTSRCPF FILE(TSTLIB/QDDSSRC)
CRTSRCPF FILE(TSTLIB/QRPGLESRC)
CRTSRCPF FILE(TSTLIB/QRPGSRC)

并将现有源代码文件从我自己的库 MYLIB/QRPGSRC 复制到 TSTLIB/QRPGSRC。然后在我定义的 MYLIB/QRPGLESRC 中创建了一个新的 ILE RPG 程序:

FQRPGSRC   IF   E           K DISK

编译时出现 2 个错误(#1 的严重性为 30,#2 的严重性为 40:RNF2121 和 RNF2109')告诉我

因为我正在阅读一些教程:我可以通过使用源代码文件的名称和记录名称轻松访问它们。但根据错误消息,只有一个记录名称,即:QRPGSRC.

添加关键字如:

FQRPGSRC   IF   E           K DISK    extfile('TSTLIB/TST001R')

没有太大帮助。现在错误仍然存​​在,但在编译输出中出现了某种 header,它向我显示了文件 (QRPGSRC) 的 "RPG-Name" 和 "External name" 以及记录格式:

*--------------------------------------------------------------------------------------------*
*                               RPG-Name         External Name                               *
* Filename   . . . . . . . . :  QRPGSRC          SYSLIB/QRPGSRC                              *
* Record format  . . . . . . :  (Not used)       QRPGSRC                                     *
*--------------------------------------------------------------------------------------------* 

为什么指定 extfile('TSTLIB/TST001R') 时 TF 在这里 SYSLIB? 当 RENAME 将 QRPGSRC 转换为 QRPGSRCR 时,不再有编译错误(除了不使用定义的文件)。

FQRPGSRC   IF   E           K DISK    extfile('TSTLIB/TST001R')
F                                     rename(QRPGSRC:QRPGSRCR) 

所以我的问题是: 我必须做什么才能像正常的 LF/PF 一样读取 PF-SRC 以便我可以 READ/CHAIN 在位于给定 [=82= 的源代码文件中的一行上]?

你快到了,但还有一些事情。

  1. 源物理文件没有键控,所以K是不正确的,如果你链接,它就会有一个相对的记录号。 READ 是此类文件的最佳选择。
  2. 当前的自由格式 RPG 可以具有子程序的本地文件声明。所以你不会总能在文件的前 50 行找到文件规范,即使你只阅读 RPGIII 文件,它们也有 50 个文件的限制,如果你包括扩展记录、注释和你的 H 规格。
  3. RPGIV对文件规格数量没有限制

鉴于这可能不是确定程序文件依赖性的最佳方法。回答您的具体问题:

FQRPGSRC   IF   E             DISK    rename(QRPGSRC:QRPGSRCR)

可能是固定格式的最佳选择。但我喜欢推广更现代的方法,所以在自由格式下它看起来更像这样:

**free
ctl-opt DftActGrp(*No) ActGrp(MyNamedAG)                            
        DatFmt(*ISO)                                           
        Option(*SrcStmt: *NoDebugIo: *NoUnref);                

dcl-f qrpgsrc qualified;                                       

dcl-ds src       LikeRec(qrpgsrc.qrpgsrc);                     

dcl-s ix         Int(5) Inz(0);                                
dcl-s FullyFree  Ind Inz(*OFF);                                

dcl-c LC         'abcdefghijklmnopqrstuvwxyz';                 
dcl-c UC         'ABCDEFGHIJKLMNOPQRSTUVWXYZ';                 

for ix = 1 to 50;                                              
  read qrpgsrc.qrpgsrc src;                                    
  if %eof();                                                   
    leave;                                                     
  endif;                                                       

  // Is this a fully free form program?                        
  if ix = 1;                                                   
    FullyFree = (%xlate(UC: LC: %trim(src.srcdta)) = '**free');
  endif;                                                       

  // Do something here                                         
endfor;
return;                                      

您将需要使用 CLP 或其他东西将源文件覆盖到适当的库,然后选择要处理的成员。这也可以在一个循环中检索所有成员,每个成员调用一次你的程序。

确定程序依赖关系的最佳方法是使用 DSPPGMREF 命令,如问题评论中所述。

如果您的系统与我见过的大多数系统一样,那么有数百个文件是通过查询创建的,sql、保存文件、工作文件等,您可能需要也可能不需要。此方法允许您拉取系统上的所有文件,并且 manipulate/analyze 随意。

我将执行 DSPOBJD(按 F4 提示)并提供以下参数: DSPOBJD OBJ(*LIBL [或特定库]/*ALL) OBJTYPE(*FILE) DETAIL(*SERVICE) OUTPUT(*OUTFILE) OUTFILE(YOURLIB/LASTUSED).

这会在您的库中创建一个您可以操作的文件...运行 SQL 删除所有使用天数 (ODUCNT) = 0 [或您的选择],以及任何内容对象属性 <> 'PF'。这只留下物理文件。

然后你可以选择最近x天内使用的对象,但你必须先将最后使用日期(ODUDAT)转换为YYMMDD格式... 更新 nwilson/lastused 设置 ODUDAT = SUBSTR(ODUDAT,5,2) 连接 substr(ODUDAT,1,4) WHERE ODUDAT <> ' '.

这将允许您比较 *DAYS 等,并构建动态语句以复制到您的开发库。

对于自动化过程,您必须执行 dsppgmref 和 prtsqlinf。

一般来说,生产数据库结构变化缓慢,每年都会有一些变化,所以我专注于将生产数据混淆到测试中。 IE 在我复制时更改个人身份信息,如 phone#s。

    set HOMEPHONE = '555-555-' 
    || cast( cast( rand(49782) * 10000  as integer) || '0000' as char(4))
WHERE homephone <> ' ';