使用 JCo 从 SAP 系统读取表

Adr*_*ian 5 java sapjco3

我试图从 SAP 系统读取表,但总是收到此错误:

Exception in thread "main" com.sap.conn.jco.JCoRuntimeException: (127) 
JCO_ERROR_FIELD_NOT_FOUND: Field EMPLOYEE is not a member of INPUT
at com.sap.conn.jco.rt.AbstractMetaData.indexOf(AbstractMetaData.java:404)
at com.sap.conn.jco.rt.AbstractRecord.setValue(AbstractRecord.java:4074)
at testConf.StepServer.main(StepServer.java:50)
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

public static void main(String[] args) {

  // This will create a file called mySAPSystem.jcoDestination
  System.out.println("executing");
  String DESTINATION_NAME1 = "mySAPSystem";

  Properties connectProperties = new Properties();
  connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "xxx.xxx.x.xxx");
  connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR,  "xx");
  connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "xxx");
  connectProperties.setProperty(DestinationDataProvider.JCO_USER,   "username");
  connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "test");
  connectProperties.setProperty(DestinationDataProvider.JCO_LANG,   "en");
  createDestinationDataFile(DESTINATION_NAME1, connectProperties);

  // This will use that destination file to connect to SAP
  try {
      JCoDestination destination = JCoDestinationManager.getDestination("mySAPSystem");
      System.out.println("Attributes:");
      System.out.println(destination.getAttributes());
      System.out.println();
      destination.ping();
  } catch (JCoException e) {
      e.printStackTrace();
  }
  try{

  //here starts the problem

  JCoDestination destination = JCoDestinationManager.getDestination(DESTINATION_NAME1);
  JCoFunction function = destination.getRepository().getFunction("RFC_READ_TABLE");
  JCoParameterList listParam = function.getImportParameterList();

  listParam.setValue("EMPLOYEE", "EMPLOYEE"); // I have found this in an example and I don't understand exactly what should I put there
                                              // I was thinking maybe is the column name but I am not sure
  function.execute(destination);

  JCoTable table = function.getTableParameterList().getTable("ZEMPLOYEES");//name of my table from SAP

  System.out.println(table);

  }
  catch (JCoException e)
  {
      System.out.println(e.toString());
      return;
  }
 }
Run Code Online (Sandbox Code Playgroud)

当显示JCO_ERROR_FIELD_NOT_FOUND: Field EMPLOYEE is not a member of INPUT but the employee is a field in my table 时,错误很明显。

在此输入图像描述

该文档没有太大帮助,它只说:

Sets the object as the value for the named field.
Parameters:
    value - the value to set for the field
    name - the name of the field to set 
Run Code Online (Sandbox Code Playgroud)

女巫,在我看来,我已经做到了。

为了从java读取这个新表,我应该在sap中进行任何额外的修改吗?我所做的就是按照本教程创建一个新表(在 SAP 中创建一个简单的表)。

也许有更多经验的人可以告诉我应该如何配置此示例代码才能工作。

Dir*_*eek 5

RFC_READ_TABLE 的一般用途

我从未使用过 JCo,但据我所知,它的接口与 .Net 连接器 NCo 非常相似。这基本上是 NCo 代码,添加了一些猜测,但它应该可以工作。

// get the table parameter FIELDS that should be in the parameter list
// the parameter table has several fields, only the field FIELDNAME has to be set before calling the function module
JCOTable inputTableParam = function.getTableParameterList().getTable("FIELDS");

// add a row to the FIELDS table parameter
inputTableParam.appendRow();

// set values for the new row
inputTableParam.setValue("FIELDNAME", "EMPLOYEE");
// just for fun, add another field to retrieve
inputTableParam.appendRow();
inputTableParam.setValue("FIELDNAME", "SURNAME");

// now we have to set the non-table parameters
JCoParameterList inputParamList = function.getImportParameterList();
// parameter QUERY_TABLE, defines which table to query
inputParamList.setValue("QUERY_TABLE", "ZEMPLOYEES");
// parameter DELIMITER - we get a single string as the return value, the field values within that string are delimited by this character
inputParamList.setValue("DELIMITER", ";");

// execute the function
function.execute(destination);

// the parameter table DATA contains the rows
JCoTable table = function.getTableParameterList().getTable("DATA");
Run Code Online (Sandbox Code Playgroud)

最后,您的变量table将保存一个表对象,其中包含一个名为 的字段WA。该字段包含您在输入参数表中选择的字段的内容FIELDS。您可以迭代table并逐行获取值。

使用 RFC_READ_TABLE 进行查询

RFC_READ_TABLE并不真正允许查询,它只允许您定义WHERE子句。该TABLE参数OPTIONS有一个字段TEXT,72 个字符宽,只能采用ABAP符合条件的WHERE子句。

为了扩展上面的示例,我们将添加一个 where 子句,以便仅从表中选择ZEMPLOYEES= SURNAME“SMITH”和FORNAME=“JOHN”的条目。

JCOTable optionsTableParam = function.getTableParameterList().getTable("OPTIONS");

// add a row to the FIELDS table parameter
optionsTableParam.appendRow();
optionsTableParam.setValue("TEXT", "SURNAME EQ 'SMITH' AND FORNAME EQ 'JOHN');
Run Code Online (Sandbox Code Playgroud)

该字段TEXT只有 72 个字符长,因此如果您想添加更长的子句,则必须手动将条件分成几行。RFC_READ_TABLE有点粗糙和有限。

表之间的复杂联接可以通过在 SAP 系统内创建视图(事务SE11)然后使用 RFC_READ_TABLE 查询该视图来实现。

If you want to call function modules from JCo, it would be very helpful if you made yourself familiar with the basic function module properties. You can look at a function module definition in transaction SE37. There you can see the IMPORT, EXPORT, CHANGING and TABLE parameters. The parameters you have to fill and the parameters that contain the results depend on the function module you call - RFC_READ_TABLE has different ones from, say, BAPI_DELIVERY_GETLIST.

Here is the documentation for JCoFunction and one of the differences between JCo and NCo, JCo has individual functions to get and set the different parameter types: https://help.hana.ondemand.com/javadoc/com/sap/conn/jco/JCoFunction.html

  • 是的,查看 JcoFunction 的文档,似乎 JCo 和 NCo 之间存在差异之一。我修改了我的示例,您本质上需要为表参数调用 getTableParameterList() ,为输入参数调用 getImportParameterList() 。 (3认同)