2015-05-06 6 views
4

Я вызываю программу RPGIV из java, программа rpgiv возвращает мультизапись в качестве выходного параметра.Как вызвать программу RPGIV из java, которая возвращает более одной записи

Я попробовал следующее, чтобы вернуть все строки, возвращенные из 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(); 
    } 

Я не знаю, как определить ParameterList [3], чтобы иметь возможность получить несколько строк назад или несколько структур данных. И как получить конкретный экземпляр выходного параметраList [3].

RPGIV код:

https://www.dropbox.com/s/a29wf1ft0f07sx1/functionCode.txt?dl=0

The * FetchedData ПРОИСХОДИТ встречается, (64) ИНЗ это выходные данные установить, что я хочу вернуться к Java.

+0

Действительно ли программа RPG возвращает несколько записей? Возвращает ли результат набор результатов? Или это массив? Измените свой вопрос, включив список параметров RPG. –

+0

@BuckCalabro Я добавил источник параметров rpgiv, FetchedData Occurs 64 - это то, что я пытаюсь вернуть. – Renier

+0

Я также вижу, что он всегда возвращает только первую запись. – Renier

ответ

3

Отредактировано, чтобы показать, как конвертировать упакованное значение.

Давайте немного сократим это. Вот небольшая 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 PROGRAMMER!), Который успешно читает различные «записи»:

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 уродлив. Я передал возвращенный байт [] в String и назначил его как блок для ds. Затем я грубо заставлял раздел кода, который подстраивал отдельные переменные один за другим. Если бы я знал больше Java, я бы, вероятно, поместил этот мусор в конструктор и, возможно, выставил его как Список.

Выложив все это, я не буду так работать с производственным кодом. Я бы попросил программистов IBM написать мне обертку вокруг SuperUltimateBlockFetch - эта оболочка вызовет SuperUltimateBlockFetch и построит результирующий набор для использования Java. Они могут даже превратить их в хранимую процедуру. Это отделит вашу зависимость от понимания внутренних принципов построения структуры RPG и сделает ее более естественной для работы с отдельными переменными в коде Java. Тогда все, что вы сделали бы, - это вызвать хранимую процедуру и написать цикл while rs.next().

+0

Спасибо, я не знал, что это будет один блок данных в байтах. Спасибо за помощь, я могу хотя бы увидеть все данные в возвращаемой строке. – Renier

+0

В вашем примере вы используете AS400Text p0000g = новый AS400Text (20); как одно из ваших полей вывода, и оно работает с подстрокой, чтобы получить правильное значение. В одном из моих примеров у меня есть AS400PackedDecimal ContactID = новый AS400PackedDecimal (9,0); Определено как одно из моих полей вывода, но при передаче его в строку для подстроки оно возвращает смешные данные. Как бы обрабатывать AS400PackedDecimal (9,0)? – Renier

+0

Вы сказали, что Parameter.getOutputData() возвращает байт []. Так есть способ получить байты поля AS400PackedDecimal (9,0), а затем преобразовать его в int? И как? или я ошибаюсь? – Renier

1

Я бы предположил, что вы не пытаетесь передать данные в качестве параметров.

Вместо этого используйте очередь данных, чтобы передать данные обратно.

Попросите программу java создать очередь данных и передать ее имя программе RPG в качестве параметра.

Программа RPG затем отправляет данные в очередь с использованием API QSNDDTAQ.

Когда управление возвращается к программе Java, попросите его прочитать записи из data queue.

+1

Очереди данных Еще одна хорошая идея. Похоже, что RPG-программа генерируется с помощью Cool: Plex/2E, поэтому любое изменение на стороне RPG, вероятно, потребует обертки, а не касаться сгенерированного кода. –