I am trying to read a table from an SAP system and I am always getting this error:
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)
And here is my code :
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;
}
}
The error is clear when it says JCO_ERROR_FIELD_NOT_FOUND: Field EMPLOYEE is not a member of INPUT but the employee is a field in my table.
The documentation doesn't help too much, it only says:
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
Witch, in my opinion, I have already done.
Should I make any additional modification in sap, in order to read this new table from java? All I have done is to create a new table following this tutorial (Create a simple table in SAP).
Maybe someone with more experience can tell me how should I configure this sample code in order to work.
I never used JCo, but as far as I know its interface is very similar to NCo, the .Net connector. This is basically NCo code with some guesswork added to it, but it should work.
// 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");
in the end, your variable table
will hold a table object with a single field called WA
. That field contains the contents of the fields you selected in input parameter table FIELDS
. You can iterate over table
and get the values row by row.
RFC_READ_TABLE
doesn't really allow queries, it only allows you to define WHERE
clauses. The TABLE
parameter OPTIONS
has a single field TEXT
, 72 characters wide, that can only take ABAP
compliant WHERE
clauses.
to extend the example above, we'll add a where clause to only select entries from table ZEMPLOYEES
with SURNAME
= "SMITH" and 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');
the field TEXT
is only 72 characters long, so if you want to add a longer clause, you manually have to break your conditions into several rows. RFC_READ_TABLE
is a bit crude and limited.
Complex joins between tables can be achieved by creating a view within the SAP system (transaction SE11
) and then query that view with 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