如何从Java调用RPGIV程序,该程序返回多个记录



我正在调用Java的RPGIV程序,RPGIV程序将多记录作为输出参数返回。

我尝试了以下内容,以返回从rpgiv返回的所有行。

   // Define Output Data Structure 
      AS400DataType[] outputData = 
    {
        new AS400Text(20),              // parentOperationsItemId;
        new AS400Text(10),              // parentOperationsItemType;
        new AS400Text(10),              // parentOperationsItemSubType;
        new AS400Text(20),              // parentKnownbyId;
        new AS400Text(10),              // parentInternalStatus;
        new AS400Text(1),               // parentLeafIndicator;
        new AS400Text(20),              // childOperationsItemId;
        new AS400Text(10),              // childOperationsItemType;
        new AS400Text(10),              // childOperationsItemSubType;
        new AS400Text(20),              // childKnownbyId;
        new AS400Text(10),              // childInternalStatus;
        new AS400Text(1),               // childLeafIndicator;
        new AS400Text(10)               // InternalStatus;
    };
AS400Structure [] outputDataConverter2 = new AS400Structure[3];
    outputDataConverter2[0] = new AS400Structure(outputData);
    outputDataConverter2[1] = new AS400Structure(outputData);
    outputDataConverter2[2] = new AS400Structure(outputData);

    Object[] dataInputInformation = 
    {
        sSqlSelect,
        sFetchDirection,
        sOperationsItemId,
        sparentOperationsItemTypeList,
        sparentOperationsItemSubTpeList,
        sparentInternalStatusList,
        schildOperationsItemType,
        schildOperationsItemSubTpeList,
        schildInternalStatusList,
        sLinkStatus
    };

    Object[] dataInputInformationControl = 
    {
        sPosition,
        new BigDecimal(sRowsFetched)
    };

    // Set up the parameter list
    ProgramParameter[] parameterList = new ProgramParameter[4];
    parameterList[0] = new ProgramParameter(7); //ReturnStatus
    parameterList[1] = new ProgramParameter(inputDataConverter.toBytes(dataInputInformation)); //Input
    parameterList[2] = new ProgramParameter(inputDataControlConverter.toBytes(dataInputInformationControl)); //Control
    parameterList[3] = new ProgramParameter(outputDataConverter2[0].getByteLength()*3); //Output

    try 
    {
        // Set the program name and parameter list.
        program.setProgram(programName, parameterList);
        // Run Function
        if (program.run() != true) 
        {
            // Calling Error
            AS400Message[] messagelist = program.getMessageList();
            for (int i = 0; i < messagelist.length; ++i) 
            {
                output[0].ReturnStatus += messagelist[i] + "n";
            }
        } 
        else 
        {
            // Set the output
            output[0] = new GetPlannedRoute();
            output[1] = new GetPlannedRoute();
            output[2] = new GetPlannedRoute();

            output[0].SetOutput(parameterList, outputDataConverter2[0]);
            output[1].SetOutput(parameterList, outputDataConverter2[1]);
            output[2].SetOutput(parameterList, outputDataConverter2[2]);
        }
    } 

这在输出类中

public void SetOutput(ProgramParameter[] parameterList, AS400Structure outputPlannedRouteConverter) 
    {
        ReturnStatus = P6Entity.CallingRPGFunction.ConvertReturnStatus(parameterList[0]);
        Object[] outputData = (Object[]) outputPlannedRouteConverter.toObject(parameterList[3].getOutputData());
        parentOperationsItemId = ((String) outputData[0]).trim();
        parentOperationsItemType = ((String) outputData[1]).trim();
        parentOperationsItemSubType = ((String) outputData[2]).trim();
        parentKnownbyId = ((String) outputData[3]).trim();
        parentInternalStatus = ((String) outputData[4]).trim();
        parentLeafIndicator = ((String) outputData[5]).trim();
        childOperationsItemId = ((String) outputData[6]).trim();
        childOperationsItemType = ((String) outputData[7]).trim();
        childOperationsItemSubType = ((String) outputData[8]).trim();
        childKnownbyId = ((String) outputData[9]).trim();
        childInternalStatus = ((String) outputData[10]).trim();
        childLeafIndicator = ((String) outputData[11]).trim();
        InternalStatus = ((String) outputData[12]).trim();
    }

我不确定如何定义参数列表[3]能够接收多个行回或多个数据结构。以及如何获得输出参数列表的特定实例[3]。

RPGIV代码:

https://www.dropbox.com/s/a29wf1ft07sx1/functioncode.txt?dl = 0

* fetcheddata发生发生(64)INZ是我要返回Java的输出数据集。

编辑以显示如何转换包装值。

让我们稍微切掉一点。这是一个小型RPG程序,其结构与您的结构相似:

 D V00001          DS                  OCCURS(64)
 D  F0000G                       20A
 D  F0000H                       10A
 D  F0000I                       10A
 D  F0000J                       20A
 D  F0000K                        9p 0
 D  F0000L                        1A
 D  F0000M                       20A
 D  F0000N                       10A
 D  F0000O                       10A
 D  F0000P                       20A
 D  F0000Q                       10A
 D  F0000R                        1A
 D  F0000S                       10A
 c     *entry        plist
 c                   parm                    v00001
   // populate the first entry
   %occur(v00001) = 1;
   F0000G = *ALL'1234567890';
   F0000H = *ALL'A';
   F0000I = *ALL'B';
   F0000J = *ALL'C';
   F0000K = 123456789;
   F0000L = *ALL'E';
   F0000M = *ALL'F';
   F0000N = *ALL'G';
   F0000O = *ALL'H';
   F0000P = *ALL'I';
   F0000Q = *ALL'J';
   F0000R = *ALL'K';
   F0000S = *ALL'a';
   // populate the 2nd entry
   %occur(v00001) = 2;
   F0000G = *ALL'1234567890';
   F0000H = *ALL'1234567890';
   F0000I = *ALL'1234567890';
   F0000J = *ALL'1234567890';
   F0000K = 200;
   F0000L = *ALL'1234567890';
   F0000M = *ALL'1234567890';
   F0000N = *ALL'1234567890';
   F0000O = *ALL'1234567890';
   F0000P = *ALL'1234567890';
   F0000Q = *ALL'1234567890';
   F0000R = *ALL'1234567890';
   F0000S = *ALL'b';
   // populate the third entry
   %occur(v00001) = 3;
   F0000G = *ALL'1234567890';
   F0000H = *ALL'1234567890';
   F0000I = *ALL'1234567890';
   F0000J = *ALL'1234567890';
   F0000K = 300;
   F0000L = *ALL'1234567890';
   F0000M = *ALL'1234567890';
   F0000N = *ALL'1234567890';
   F0000O = *ALL'1234567890';
   F0000P = *ALL'1234567890';
   F0000Q = *ALL'1234567890';
   F0000R = *ALL'1234567890';
   F0000S = *ALL'c';
   // reset back to the beginning
   %occur(v00001) = 1;
   dump(a);
   *inlr = *on;

这是Java(我不是Java程序员!),成功读取各种"记录":

public String testSO(AS400 system, String programName) {
    boolean success = false;
    final int ONE_ROW_LEN = 147;
    final int DS_ROWS = 64;
    AS400Text dsText = new AS400Text(ONE_ROW_LEN * DS_ROWS);
    AS400Text p0000g = new AS400Text(20);
    AS400Text p0000h = new AS400Text(10);
    AS400Text p0000i = new AS400Text(10);
    AS400Text p0000j = new AS400Text(20);
    int p0000k;  // packed(9, 0) is 5 bytes
    AS400Text p0000l = new AS400Text( 1);
    AS400Text p0000m = new AS400Text(20);
    AS400Text p0000n = new AS400Text(10);
    AS400Text p0000o = new AS400Text(10);
    AS400Text p0000p = new AS400Text(20);
    AS400Text p0000q = new AS400Text(10);
    AS400Text p0000r = new AS400Text( 1);
    AS400Text p0000s = new AS400Text(10);
    String ds = null;
    String returnString = null;
    try
    {
        ProgramCall program = new ProgramCall(system);
        // Set up the parameter list
        ProgramParameter[] parameterList = new ProgramParameter[1];
        parameterList[0] = new ProgramParameter(ONE_ROW_LEN * DS_ROWS); 
        program.setProgram(programName, parameterList);
        success = program.run();
        if(success!=true){
            AS400Message[] messagelist = program.getMessageList();
            System.out.println("nMessages received:n");
            for (int i = 0; i < messagelist.length; i++) {
                System.out.println(messagelist[i]);
            }
        } else {
            // RPG is returning a giant chunk of memory
            //allBytes = parameterList[0].getOutputData();
            ds = (String)dsText.toObject(parameterList[0].getOutputData());
            System.out.println("ds=" + ds);
            System.out.println("ds len=" + ds.length());
            // Need to index our way into the block of memory
            // zero-based!
            int row = 0;
            int x = row * ONE_ROW_LEN;
            System.out.println("x=" + x);
            // parse out the individual elements for this row
            int len = p0000g.getByteLength();
            String s0000g = ds.substring(x, x+len);
            x += len;
            len = p0000h.getByteLength();
            String s0000h = ds.substring(x, x+len);
            x += len;
            len = p0000i.getByteLength();
            String s0000i = ds.substring(x, x+len);
            x += len;
            len = p0000j.getByteLength();
            String s0000j = ds.substring(x, x+len);
        // this is packed(9, 0)
        x += len;
        len = 5;
        byte[] b0000k = dsText.toBytes(ds.substring(x, x+len));
        BigDecimal d0000k = (BigDecimal)new AS400PackedDecimal(9, 0).toObject(b0000k);
        p0000k = d0000k.intValue();
        String s0000k = d0000k.toString();
            x += len;
            len = p0000l.getByteLength();
            String s0000l = ds.substring(x, x+len);
            x += len;
            len = p0000m.getByteLength();
            String s0000m = ds.substring(x, x+len);
            x += len;
            len = p0000n.getByteLength();
            String s0000n = ds.substring(x, x+len);
            x += len;
            len = p0000o.getByteLength();
            String s0000o = ds.substring(x, x+len);
            x += len;
            len = p0000p.getByteLength();
            String s0000p = ds.substring(x, x+len);
            x += len;
            len = p0000q.getByteLength();
            String s0000q = ds.substring(x, x+len);
            x += len;
            len = p0000r.getByteLength();
            String s0000r = ds.substring(x, x+len);
            x += len;
            len = p0000s.getByteLength();
            String s0000s = ds.substring(x, x+len);

            returnString = s0000s;
            System.out.println("Return=" + returnString);
            System.out.println("g=" + s0000g);
            System.out.println("h=" + s0000h);
            System.out.println("i=" + s0000i);
            System.out.println("i=" + s0000i);
            System.out.println("j=" + s0000j);
            System.out.println("k=" + s0000k);
            System.out.println("l=" + s0000l);
            System.out.println("m=" + s0000m);
            System.out.println("n=" + s0000n);
            System.out.println("o=" + s0000o);
            System.out.println("p=" + s0000p);
            System.out.println("q=" + s0000q);
            System.out.println("r=" + s0000r);
            System.out.println("r=" + s0000s);
        }
    } catch (Exception e) {
        System.out.println("ne:n");
        System.out.println(e);
        System.out.println("nStack trace:n");
        e.printStackTrace();
    }
    return returnString;
}

在Java中了解的关键部分是,使用此设计,parameter.getOutputdata()正在返回字节[]。我不是Java程序员,所以我的Java代码很丑陋。我将返回的字节[]施加到字符串中,并将其分配为DS的块。然后,我违反了一部分代码,将单个变量逐一缩小。如果我知道更多的Java,我可能会将垃圾放在构造函数中,并可能将其视为列表。

发布了所有这些内容,我无法使用生产代码这样操作。我会让IBM程序员在SuperultimateBlockfetch周围给我写一份包装器 - 该包装器会调用SuperultimateBlockfetch,并构建Java使用的结果集。他们甚至可以将其制定为存储过程。这将使您对理解RPG结构的内部构建的内部依赖,并使处理Java代码中的单个变量变得更加自然。然后,您要做的就是调用存储过程并编写while rs.next()循环。

我建议您不要尝试将数据传递为参数。

而是使用数据队列将数据传递回。

让Java程序创建一个数据队列并将其名称传递给RPG程序作为参数。

然后,RPG程序将使用QSNDDTAQ API将数据发送到队列。

当控件返回Java程序时,请读取数据队列中的条目。

相关内容

  • 没有找到相关文章

最新更新