使用Java从SAP系统读取表

时间:2018-09-06 10:02:12

标签: sap abap 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)

这是我的代码:

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:该字段不是INPUT的成员,但该雇员是我表中的一个字段时,此错误很明显。

enter image description here

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

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 

我认为巫婆已经做完了。

为了从Java读取此新表,是否应该对sap进行任何其他修改?我要做的就是按照本教程(Create a simple table in SAP)创建一个新表。

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

3 个答案:

答案 0 :(得分:3)

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将包含一个表对象,该表对象具有一个称为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');

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

表之间的复杂联接可以通过在SAP系统中创建一个视图(事务SE11),然后使用RFC_READ_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

答案 1 :(得分:2)

您试图调用函数RFC_READ_TABLE,并且尝试将值传递给名为“ EMPLOYEE”的参数。这不是RFC_READ_TABLE的参数,因此是错误。

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

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

RFC_READ_TABLE具有1个返回参数:

  • DATA:表的内容

请参见以下示例:https://vishalmasih.wordpress.com/2014/10/31/sap-jco-searching-for-a-user-in-the-usr04-table/

答案 2 :(得分:0)

这个适合您吗?我尝试了您的代码,但遇到了同样的错误。我仍然不知道我应该把Tablename和Fieldname放在哪里。 我添加了Dirk Trilsbeek的代码,但再也没有收到任何错误,但是我得到的只是:

| ---------------------------------------------- -------------------------- | |表'RFC_DB_OPT' | ------------------------------------------------- ----------------------- | |文字| | ------------------------------------------------- ----------------------- | | 012345678901234567890123456789012345678901234567890123456789012345678901 | | ------------------------------------------------- ----------------------- |

| ---------------------------------------------- -------------------------- |

我应该怎么做?这是哪里来的/为什么来的?