使用 JCo 从 SAP 系统读取 table

Read a table from a SAP system using JCo

我正在尝试从 SAP 系统读取 table,但我总是收到此错误:

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)

这是我的代码:

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;
  }
 }

当它说 JCO_ERROR_FIELD_NOT_FOUND 时,错误很明显:字段 EMPLOYEE 不是 INPUT 的成员,但该员工是我的 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 

,在我看来,我已经做到了

我是否应该在 sap 中进行任何额外的修改,以便从 java 读取这个新的 table?我所做的就是按照本教程 (Create a simple table in SAP) 创建一个新的 table。

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

一般使用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");

最后,您的变量 table 将包含一个 table 对象,其中包含一个名为 WA 的字段。该字段包含您在输入参数 table FIELDS 中 select 编辑的字段的内容。您可以遍历 table 并逐行获取值。

查询 RFC_READ_TABLE

RFC_READ_TABLE 实际上不允许查询,它只允许您定义 WHERE 子句。 TABLE 参数 OPTIONS 有一个字段 TEXT,72 个字符宽,只能采用 ABAP 兼容的 WHERE 子句。

为了扩展上面的示例,我们将仅向来自 table ZEMPLOYEESSURNAME = "SMITH" 的 select 条目添加一个 where 子句,并且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');

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

可以通过在 SAP 系统中创建视图(事务 SE11)然后使用 RFC_READ_TABLE.

查询该视图来实现 table 之间的复杂连接

如果你想从JCo调用功能模块,熟悉基本的功能模块属性会很有帮助。您可以查看事务SE37中的功能模块定义。在那里您可以看到 IMPORTEXPORTCHANGINGTABLE 参数。您必须填写的参数和包含结果的参数取决于您调用的功能模块 - RFC_READ_TABLEBAPI_DELIVERY_GETLIST.

不同。

这是 JCoFunction 的文档以及 JCo 和 NCo 之间的区别之一,JCo 有单独的函数来获取和设置不同的参数类型:https://help.hana.ondemand.com/javadoc/com/sap/conn/jco/JCoFunction.html

您正在尝试调用函数 RFC_READ_TABLE,并尝试将一个值传递给名为 "EMPLOYEE" 的参数。这不是 RFC_READ_TABLE 的参数,因此是错误。

RFC_READ_TABLE有3个重要的输入参数:

  • QUERY_TABLE :要查询的数据库table的名称
  • OPTIONS : WHERE 子句(你可以传递一个空值)
  • FIELDS : 您要查询的数据库table中的列列表

RFC_READ_TABLE 有 1 个 return 参数:

  • DATA : table
  • 的内容

看这个例子:https://vishalmasih.wordpress.com/2014/10/31/sap-jco-searching-for-a-user-in-the-usr04-table/