使用 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 ZEMPLOYEES
且 SURNAME
= "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
中的功能模块定义。在那里您可以看到 IMPORT
、EXPORT
、CHANGING
和 TABLE
参数。您必须填写的参数和包含结果的参数取决于您调用的功能模块 - RFC_READ_TABLE
与 BAPI_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/
我正在尝试从 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 ZEMPLOYEES
且 SURNAME
= "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.
如果你想从JCo调用功能模块,熟悉基本的功能模块属性会很有帮助。您可以查看事务SE37
中的功能模块定义。在那里您可以看到 IMPORT
、EXPORT
、CHANGING
和 TABLE
参数。您必须填写的参数和包含结果的参数取决于您调用的功能模块 - RFC_READ_TABLE
与 BAPI_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/