Api 如何从RPG程序创建新的文件成员?

Api 如何从RPG程序创建新的文件成员?,api,ibm-midrange,rpgle,Api,Ibm Midrange,Rpgle,我需要为RPG程序中的现有物理文件创建一个新成员。我知道两种方法,而且我必须说,这两种方法我都不喜欢: 使用QCMDEXC调用ADDPFM 编写一个CL程序,调用ADDPFM并从RPG调用它 第一种方法是将一个必须由QCMDEXC解析的命令组合在一起,该命令的性能听起来不太好(我知道,这里的扩展部分不是调用,而是成员的创建)——但真正困扰我的是,我觉得它并不简单,但恰恰相反,很难理解,也不太美观 第二种方法使用编译程序,因此不涉及具体化和解析。而且,它在您的RPG代码中看起来并不可怕,因为它只是

我需要为RPG程序中的现有物理文件创建一个新成员。我知道两种方法,而且我必须说,这两种方法我都不喜欢:

  • 使用
    QCMDEXC
    调用
    ADDPFM
  • 编写一个CL程序,调用
    ADDPFM
    并从RPG调用它
  • 第一种方法是将一个必须由
    QCMDEXC
    解析的命令组合在一起,该命令的性能听起来不太好(我知道,这里的扩展部分不是调用,而是成员的创建)——但真正困扰我的是,我觉得它并不简单,但恰恰相反,很难理解,也不太美观

    第二种方法使用编译程序,因此不涉及具体化和解析。而且,它在您的RPG代码中看起来并不可怕,因为它只是一个普通的过程调用。但我必须创建一个额外的外部程序,该程序需要传输到我的RPG程序将要使用的所有系统。这也有点与我的审美观相冲突,仅仅为了一个api调用就创建了一个额外的源代码和二进制代码

    有没有一种方法可以直接调用api,而无需
    QCMDEXC
    ?或者是另一种为PF创建新成员的RPGish方式?谷歌对我毫无帮助


    谢谢

    无法从RPG中直接创建物理文件成员

    您列出的选项很好。另一个是system()API。如果这是一个新的应用程序,尽量避免多个成员;他们不是SQL的朋友。传统的多成员应用程序在调用RPG之前使用包装器CL处理ADDPFM和OVRDBF:

    PGM &month
    DCL &month *char 3
    DCL &mbr *char 10
    chgvar &mbr ('SALES' *cat &month)
    addpfm sales &mbr
    monmsg...
    ovrdbf sales mbr(&mbr)
    call RPG_PGM
    endpgm
    

    显然,对于RPG的最新版本,我们可以在F规范中进行覆盖。但是仍然没有办法直接从RPG内部操纵文件成员。我倾向于为system()或QCMDEXC编写过程包装,并将其放在服务程序中,这样我就可以从RPG程序中执行操作系统级的工作。如果愿意,可以编写一个特定的ADDPFM过程并调用该“API”。

    以给出
    QCMDEXC
    解决方案的一些示例。如果您只需要在RPG程序中使用某种方式来创建成员,而不想添加任何其他(CL-)程序,那么这是一个简单的解决方案:

    您可以这样创建一个过程
    crt\u mbr

     Pcrt_mbr          B
     D                 PI
     D lib                           10A   value
     D file                          10A   value
     D mbr                           10A   value
     Dqcmdexc          PR                  extpgm('QCMDEXC')
     D str                          200a   options(*varsize) const
     D len                           15P 5 const
     Dcmd              S            200A
     Dlen              S             15P 5
      /free
       cmd = 'ADDPFM FILE('+%trimr(lib)+'/'+%trimr(file)+') ' +
             'MBR(' + %trimr(mbr) +')';
       len = %len(%trimr(cmd));
       qcmdexc(cmd: len);
      /end-free
     Pcrt_mbr          E
    
    在v7中,它可以如下所示:

    dcl-proc crt_mbr;
      dcl-pi *n;
        lib    char(10) value;
        file   char(10) value;
        mbr    char(10) value;
      end-pi;
    
      dcl-pr qcmdexc  extpgm('QCMDEXC');
        str    char(200) options(*varsize) const;
        len    packed(15:5) const;
      end-pr;
    
      dcl-s cmd    char(200) inz('');
      dcl-s len    packed(15:5) inz(0);
    
      cmd = 'ADDPFM FILE(' + %trimr(lib) + '/' + %trimr(file) + ')' +
            ' MBR(' + %trimr(mbr) + ')';
      qcmdexc(cmd: %len(%trimr(cmd)));
    end-proc;
    
    您可能需要在程序开始时添加原型(取决于您的版本):

    知道在您的程序中,您可以直接调用:

    /free
     ...
     crt_mbr('MY_LIB': 'MY_FILE': 'NEW_MEMBER');
     ...
    /end-free
    

    请注意,这根本没有错误处理。因此,如果文件allready包含该名称的成员,您的程序将转储。根据需要添加监控或不同的错误处理。

    在使用RPG时,你不能有太严格的美感。它不是一种漂亮的语言,
    QCMDEXC
    是从RPG调用系统命令的正常方式。这就是它的目的。@johnY实际上,RPG的混乱让我更加关注我的美感。否则,你将失去你正在做的一切。你可以在RPG中编写非常难看的代码,但是你可以使用样式(在大多数地方),如果你知道如何(并且有勇气…)的话。我想说的是,如果你以尽可能漂亮的方式编写RPG,它仍然不是很漂亮。根据RPG标准,调用另一个程序(无论是您自己编写的自定义CLP还是
    QCMDEXC
    )并不难看。你给出的选择实际上在概念上非常简单,而且不难遵循,特别是对于那些习惯于使用RPG编程的人来说。同意John Y的观点,所给出的选择对于RPG程序员来说并不难遵循。我想补充一点,如果你为QCMDEXC编写一个包装程序,你就可以得到外观更好的代码。可以使用addpfm(文件:mbr)代替callp qcmdexc(cmd:%len(cmd)),并让addpfm过程格式化字符串以传递到qcmdexc。@kratenko:CL过程工作正常,而不是第二个*PGM。您仍然有一台*PGM;它有两个绑定*模块,一个RPG和一个CL,一个要分发的对象。就个人而言,我更喜欢CL模块而不是QCMDEXC。当CL编译器有内置的工具时,我不认为尝试动态生成命令然后处理可能的错误有多大用处。所以没有,我担心这不是。。。所以我一直坚持用外部的方法来做到这一点。我已经在通过F规格中的变量进行覆盖了。它是一个平面文件,因此不涉及SQL。感谢您提供的额外提示和全面的胜任回答。事实表明,就性能而言,
    const
    通常优于
    value
    ,并且很少有情况需要
    value
    /free
     ...
     crt_mbr('MY_LIB': 'MY_FILE': 'NEW_MEMBER');
     ...
    /end-free