1
Access to the SAP BW ODS BAPI using C# and SAP .NET Connector 2.0 Hermann Däubler, Program Manager, Microsoft Corporation
Summary The following paper should help to get a quick start on how to access the ODS BAPI in
SAP BW using the new SAP .Net Connector 2.0. The main focus is to demonstrate how
easy it became to call the BAPI functions as SAP .NET Connector generates all the
code which is necessary to handle the RFC ( Remote Function Call ) part. What’s still
left to the programmer is the connection to the BW system and processing BAPI result
sets which of course might be still quite some work.
Applies to SAP BW 3.0B, Basis SP 39, ABAP SP 39, BW SP 21 SAP .NET Connector 2.0 Microsoft Visual Studio .NET 2003
Keywords ODS BAPI, SAP .NET Connector, C#
Level of difficulty Technical consultants, Developers
Contact For feedback or questions you can contact the Collaboration Technology Support Center at [email protected]. Please check the .NET interoperability area in the SAP Developer Network http://www.sdn.sap.com/sdn/developerareas/dotnet.sdn for any updates or futher information .
Collaboration Technology Support Center - Microsoft - Collaboration Brief September 2004
2
Copyright 2004 SAP AG. All rights reserved. All other product and service names mentioned are the trademarks of their respective companies No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP AG. The information contained herein may be changed without prior notice.. Some software products marketed by SAP AG and its distributors contain proprietary software components of other software vendors. Microsoft, Windows, Outlook, and PowerPoint are registered trademarks of Microsoft Corporation. IBM, DB2, DB2 Universal Database, OS/2, Parallel Sysplex, MVS/ESA, AIX, S/390, AS/400, OS/390, OS/400, iSeries, pSeries, xSeries, zSeries, z/OS, AFP, Intelligent Miner, WebSphere, Netfinity, Tivoli, and Informix are trademarks or registered trademarks of IBM Corporation in the United States and/or other countries. Oracle is a registered trademark of Oracle Corporation. UNIX, X/Open, OSF/1, and Motif are registered trademarks of the Open Group. Citrix, ICA, Program Neighborhood, MetaFrame, WinFrame, VideoFrame, and MultiWin are trademarks or registered trademarks of Citrix Systems, Inc. HTML, XML, XHTML and W3C are trademarks or registered trademarks of W3C®, World Wide Web Consortium, Massachusetts Institute of Technology. Java is a registered trademark of Sun Microsystems, Inc. JavaScript is a registered trademark of Sun Microsystems, Inc., used under license for technology invented and implemented by Netscape. MaxDB is a trademark of MySQL AB, Sweden. SAP, R/3, mySAP, mySAP.com, xApps, xApp, SAP NetWeaver, and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and in several other countries all over the world. All other product and service names mentioned are the trademarks of their respective companies. Data contained in this document serves informational purposes only. National product specifications may vary. These materials are subject to change without notice. These materials are provided by SAP AG and its affiliated companies ("SAP Group") for informational purposes only, without representation or warranty of any kind, and SAP Group shall not be liable for errors or omissions with respect to the materials. The only warranties for SAP Group products and services are those that are set forth in the express warranty statements accompanying such products and services, if any. Nothing herein should be construed as constituting an additional warranty.
3
Contents Summary .............................................................................................................1 Applies to ............................................................................................................1 Keywords.............................................................................................................1 Level of difficulty ................................................................................................1 Contact ................................................................................................................1 Contents ..............................................................................................................3 Introduction.........................................................................................................4 SAP BW Demo Cube 0D_DECU.........................................................................5
Activating demo cube 0D_DECU ............................................................................................ 5 Loading data into the demo cube 0D_DECU ......................................................................... 6 Issues loading the demo cube 0D_DECU .............................................................................. 6
Creating an ODSObject ......................................................................................7 SAP BW ODS BAPI ...........................................................................................10 Code sample .....................................................................................................11
Use SAP BW ODS BAPI methods to retrieve metadata and extract data......................... 11 Source listing of C# sample ( shows all ODS objects and extracts data from ODS object ODSDECU ) ............................................................................................................................. 15
Conclusion ........................................................................................................22 Limitations.........................................................................................................22 References ........................................................................................................23
4
Introduction
It might be useful in certain customer scenarios to extract data from SAP BW using a
self-written program instead of a full-blown reporting tool. This paper shows how easy it
is to call the SAP BW ODS BAPI functions with the help of SAP .NET Connector 2.0.
ODSObjects are not based on a star or snowflake schema. They are “flat” structures
without separate dimension tables. But it might be still necessary to join to the master
data tables in order to get text data or to work with hierarchies. Due to this flat structure
no MDX ( Multidimensional eXpression ) language is needed ( like for the OLAP BAPI )
to retrieve data from an ODSObject which makes life easier. What needs to be done is
just to specify all the parameters for the read call of the ODS BAPI.
The sample is based on a SAP demo cube which is part of the business content
in SAP BW. Therefore it should be possible for every SAP BW 3.0B customer
to setup the same environment which was used for the sample.
5
SAP BW Demo Cube 0D_DECU
To use exactly the same test environment which was used for the sample it’s
necessary to activate the 0D_DECU demo cube.
Activating demo cube 0D_DECU The cube can be activated in the administrator workbench ( transaction RSA1 )
under section “Business Content” :
Figure 1 : demo cube activation
6
Loading data into the demo cube 0D_DECU When the demo cube is activated you will find several .CSV load files in the SAP work
directory. Use the appropriate InfoSources and InfoPackages to load the master data
and the InfoCube ( fact table ) :
Figure 2 : load files for demo cube
Issues loading the demo cube 0D_DECU SAP Note 370397 provides some hints regarding loading the SAP demo cubes. There
were two issues related to loading the .CSV files. A few files contained some additional
character after the last data row which confused BW. A simple workaround was to open
the .CSV file in Notepad and delete any additional ‘newline’ or whatever at the end ( just
use DEL or BACKSPACE until the cursor stands directly next to the last visible
character in the data file ).
The second issue was more difficult to solve. For whatever reason the order of the
columns in two .CSV files ( master data for 0D_SOLD_TO and trans data for the fact
table ) was different than the transfer structure which was generated. The solution was
to change the order of the columns in the DataSource/Transfer Structure.
7
For 0D_SOLD_TO it has to be :
0D_SOLD_TO, 0D_COUNTRY, 0D_INDUSTRY, 0LONGITUDE, 0LATITUDE,
0ALTITUDE, 0SRCID, 0PRECISID, 0D_REGION, 0D_CITY, 0D_STREET, 0D_PHONE
For the fact table it has to be :
D_CO_CODE, D_DIS_CHAN, D_DIV, D_MATERIAL, D_PROD_HIE, D_SALE_EMP,
D_SALE_ORG, D_SOLD_TO, D_VERSION, D_INV_QTY, SALES_UNIT, D_COST,
DOC_CURRCY, D_NETVLINV, D_TAXAMOUN, CALDAY, D_VTYPE
Creating an ODSObject The ODSObject in the sample was created manually. The idea was to use the same
InfoObjects which were used in the sample query of the “OLAP BAPI white paper” in
order to make the output of the ODS query comparable. See the following screenshot
regarding the definition of the ODSObject.
Figure 3 : structure of the ODSObject
8
To load the ODSObject with the same data as the demo InfoCube the InfoSource of
0D_DECU was copied. When creating the default update rules an error message
showed up which complained about a missing InfoObject ( 0RECORDMODE ) in the
communication structure. This is needed in an ODSObject. But it doesn’t exist in the
load files for the demo InfoCube. Therefore the solution was to add this InfoObject to the
communication structure and set a constant value in the transfer structure. There was a
little issue as the selection list for a constant didn’t show any values :
Figure 4 : no selection of constant values for InfoObject 0RECORDMODE
The workaround was to choose a formula ( called it “recmodeconst” ) and then select a
constant in the formula screen. Here the selection list of possible constants worked fine.
The value ‘ ‘ ( blank ) which means “After-Image” was selected :
9
Figure 5 : selection of constant value ‘After-Image’ for InfoObject 0RECORDMODE in the “formula screen”
After the ODSObject was created the standard procedures followed to load and activate
an ODSObject ( not covered in this document ). Just don’t forget to set the update type
of the data fields in the ODSObject to “Addition” ( change update rules ). The default is
“Overwrite” which finally leads to a different query result than the sample query in the
“OLAP BAPI white paper”. The reason is that there are duplicate values for the key
columns. In case of “Overwrite” you would get only the data values of the last row which
was loaded for a certain combination of keys.
10
SAP BW ODS BAPI You will find infos about the ODS BAPI in the function module documentation using
transaction SE37. The following screenshot shows the info for the function
BAPI_ODSO_READ_DATA_UC. The sample uses the non-Unicode version. But it
turned out that the docu for the Unicode version includes a more detailed description
of the function. There you will find e.g. the list of possible function parameters.
Figure 6 : function module documentation of ‘BAPI_ODSO_READ_DATA_UC’ Two function calls are basically necessary to read data from an ODSObject :
BAPI_ODSO_GETLIST() to find an ODSObject ( in case the name shouldn’t
be hard-coded ) and BAPI_ODSO_READ_DATA() to read data from it ( or
BAPI_ODSO_READ_DATA_UC() for Unicode systems ).
11
Code sample Use SAP BW ODS BAPI methods to retrieve metadata and extract data After you installed SAP .NET Connector open a new C# Console Program Project in
Visual Studio .NET and add the SAP Connector Proxy ( in Solution Explorer right-click
on the project name and choose “Add”->”Add New Item …” ). More infos can be found
in the description and the samples which come with the SAP .NET Connector. After
adding the Proxy click on “Build”->”Build Solution”.
Figure 7 : SAP Connector Proxy
Configure the connection to the BW application server in the “Server Explorer” window.
In the folder BOR you can use the subfolder “Alphabetical” to find the OLAP BAPI
functions. :
12
Figure 8 : looking for ODS BAPI methods
Under “ODSObject” choose GetList as well as ReadData and put it via “drag&drop” on
the design window of the generated SAPProxy. SAP .NET Connector generates code to
call the BAPI functions and to define the parameters which are needed. By “moving” the
BAPI methods to the design window it will automatically add icons for the additional
classes which are needed to handle the method parameters and result sets. In the
“code-view” of the SAPProxy1.cs file you will find the BAPI calls and which parameters
are used. SAP .NET Connector generated classes with slightly different names :
“GetList” became “Bapi_Odso_GetList()” and “ReadData” became
“Bapi_Odso_Read_Data”. Before you continue click on “Build”->”Build Solution”.
13
Figure 9 : choosing ODS BAPI methods “GetList” and “ReadData”
The ODS BAPI method Bapi_Odso_Getlist() is very easy to handle. To list all ODSObjects in the BW system just call the function using the appropriate parameters and loop thru the result set to print all object names. The following screenshot shows the output of the first part of the C# sample :
Figure 10 : output of C# sample – retrieving BW metadata ( existing ODSObjects )
14
The ODS BAPI method Bapi_Odso_Read_Data() is also pretty easy to use. The sample
code shows how to specify search conditions for the values of the fields in the
ODSobject as well as the possibility to extract only certain fields instead of all of them.
The function uses neither MDX nor SQL which makes life much easier. Also processing
of the result set isn’t as complex as in the OLAP BAPI sample. The result set is just a list
of rows. Every row comes back as one string. In case all the fields of the ODSObject
which were selected would sum up to a rowlength of more then 250 bytes a second
string would belong to the same row and so on. This adds a bit complexity to the
processing. Metadata ( structure of the string which represents a row ) is provided in a
separate structure. The following screenshot shows the output of the second part of the
C# sample. The values of the key figures ( data fields of the ODSObject ) are identical to
the MDX query output of the “OLAP BAPI white paper” sample. The big difference are
the key fields. Here we get only the IDs for 0D_CO_CODE and 0D_SOLD_TO. The text
info from the master data tables is not available thru the ODS BAPI.
Figure 11 : output of C# sample – extracting data from the ODSObject
15
Source listing of C# sample ( shows all ODS objects and extracts data from ODS object ODSDECU )
IMPORTANT : if you just copy the following code into Visual Studio you will get
errors during compilation in case you chose a different name than
SDNC_SAMPLE03 for your C# project. So just change the
namespace in the source listing accordingly.
using System; using SAP.Connector; namespace SDNC_SAMPLE03 { class Class1 { [STAThread] static void Main(string[] args) { // variables for processing the result set // and formatting on the screen as well as // parameters for the BAPI call int nr_odsobj=0; int nr_rs_rows=0; int nr_rs_cols=0; int infobj_offset=2; int ods_col_length=0; int max_ods_col_length=12; int ods_col_offset=0; int ods_max_rows=0; int ods_lines_per_record=0; int ods_nr_rows=0; string ods_objname=""; string ods_colname=""; string rs_currency=""; string rs_salesunit=""; // parameters for BAPI call BAPIRET2 ods_ret2; BAPI6116LTable ods_ltab = new BAPI6116LTable(); BAPI6116L ods_lrow; BAPI6116SLTable ods_sl16tab = new BAPI6116SLTable(); BAPI6100SLTable ods_sl00tab = new BAPI6100SLTable(); BAPI6116DALOTable ods_dalotab = new BAPI6116DALOTable(); BAPI6116DALO ods_dalorow; BAPI6116IOLSTable ods_iolstab = new BAPI6116IOLSTable(); BAPI6116IOLS ods_iolsrow; BAPI6116IOLSTable ods_iolsotab = new BAPI6116IOLSTable();
16
BAPI6116DATable ods_datab = new BAPI6116DATable(); BAPI6116DA ods_darow; BAPI6116SLIOTable ods_sliotab = new BAPI6116SLIOTable(); BAPI6116SLIO ods_sliorow; // assemble connection string Destination bw_system = new Destination(); bw_system.AppServerHost = "hdmbw30b"; bw_system.Username = "rosetta"; bw_system.Password = "obelix"; bw_system.Client = 900; bw_system.SystemNumber = 1; // establish connection to BW SAPProxy1 sap_bw_proxy = new SAPProxy1(bw_system.ConnectionString); // BAPI call to get the list of all ODS objects // in the BW system. The first parameter ( object version ) // is set to 'A' to look only for "active" objects. // No selection criteria is specified. See the function // module documentation using transaction SE37 in BW and // type in "BAPI_ODSO_GETLIST" for more infos. sap_bw_proxy.Bapi_Odso_Getlist("A", out ods_ret2, ref ods_ltab, ref ods_sl16tab, ref ods_sl00tab ); // process the result set Console.Write("Number of ODS objects found : "); Console.WriteLine(ods_ltab.Count); for( nr_odsobj=0; nr_odsobj<ods_ltab.Count; nr_odsobj++ ) { ods_lrow = ods_ltab[nr_odsobj]; Console.WriteLine(); Console.WriteLine("ODS object "+(nr_odsobj+1)); Console.WriteLine(); Console.WriteLine(" ODS Object : "+ods_lrow.Odsobject); Console.WriteLine(" Infoarea : "+ods_lrow.Infoarea); Console.WriteLine(" Long descr : "+ods_lrow.Textlong); Console.WriteLine(); } Console.WriteLine("Press RETURN"); Console.ReadLine(); // look for the demo ODS object ods_objname = "ODSDECU"; for( nr_odsobj=0; nr_odsobj<ods_ltab.Count; nr_odsobj++ ) { if( ods_ltab[nr_odsobj].Odsobject.Equals(ods_objname) ) break; } if( nr_odsobj >= ods_ltab.Count ) { Console.WriteLine("ODS object "+ods_objname+" not found !"); Console.WriteLine();
17
Console.WriteLine("Press RETURN"); Console.ReadLine(); return; } ods_lrow = ods_ltab[nr_odsobj]; // instead of selecting all fields from the ODS // object just select certain InfoObjects. The // result set will deliver them in the same order // as they were added in the following list. // // One issue – ‘currency’ and ‘unit’ will be delivered // as separate InfoObjects ( columns in the result ). // But there are two key figures in the result which // need the ‘currency’ added at the end of the string // to get a nice output. Therefore ‘currency’ and ‘unit’ // are put at the beginning of the list to make processing // of the result set easier later on. ods_iolsrow = new BAPI6116IOLS(); ods_iolsrow.Infoobject = "0DOC_CURRCY"; ods_iolstab.Add(ods_iolsrow); ods_iolsrow = new BAPI6116IOLS(); ods_iolsrow.Infoobject = "0SALES_UNIT"; ods_iolstab.Add(ods_iolsrow); ods_iolsrow = new BAPI6116IOLS(); ods_iolsrow.Infoobject = "0D_CO_CODE"; ods_iolstab.Add(ods_iolsrow); ods_iolsrow = new BAPI6116IOLS(); ods_iolsrow.Infoobject = "0D_SOLD_TO"; ods_iolstab.Add(ods_iolsrow); ods_iolsrow = new BAPI6116IOLS(); ods_iolsrow.Infoobject = "0D_COST"; ods_iolstab.Add(ods_iolsrow); ods_iolsrow = new BAPI6116IOLS(); ods_iolsrow.Infoobject = "0D_NETVLINV"; ods_iolstab.Add(ods_iolsrow); ods_iolsrow = new BAPI6116IOLS(); ods_iolsrow.Infoobject = "0D_INV_QTY"; ods_iolstab.Add(ods_iolsrow); // define the selection criteria. It's possible // to specify certain restrictions for every // InfoObject in the result. // See the function module documentation in // transaction SE37 for more infos about the // available options. But use the function name // BAPI_ODSO_READ_DATA_UC. The docu for the // Unicode version of the function provides more // details. // In the following code "BT" means "between" // ( between high and low value ). "I" means // that the boundary values should be included. ods_sliorow = new BAPI6116SLIO(); ods_sliorow.Iobjnm = "0D_CO_CODE";
18
ods_sliorow.Low = "1000"; ods_sliorow.High = "2000"; ods_sliorow.Opt = "BT"; ods_sliorow.Sign = "I"; ods_sliotab.Add(ods_sliorow); ods_sliorow = new BAPI6116SLIO(); ods_sliorow.Iobjnm = "0D_SOLD_TO"; ods_sliorow.Low = "0000002100"; ods_sliorow.High = "0000002500"; ods_sliorow.Opt = "BT"; ods_sliorow.Sign = "I"; ods_sliotab.Add(ods_sliorow); // call the BAPI function to read data from // the ODSObject. If the third parameter is // empty it means that the InfoObject list // should be considered. If set to 'X' means // to select ALL InfoObjects. sap_bw_proxy.Bapi_Odso_Read_Data( ods_max_rows, ods_lrow.Odsobject, "", out ods_lines_per_record, out ods_nr_rows, out ods_ret2, ref ods_dalotab, ref ods_iolstab, ref ods_iolsotab, ref ods_datab, ref ods_sliotab ); // process the result set // // IMPORTANT : // Every row is returned as a string. If the string is // longer than 250 characters it's split. Therefore the // BAPI call parameter "ods_lines_per_record" exists. // In the sample all InfoObjects fit in one string which // makes the processing easier. Console.WriteLine("Result Set : "); Console.WriteLine(); // go thru all rows in the result set for(nr_rs_rows=0; nr_rs_rows<ods_datab.Count; nr_rs_rows++) { ods_darow = ods_datab[nr_rs_rows]; if( ods_dalotab.Count > 0 ) { // get the currency text from the current result row. // Method get_rs_value() is defined further down. get_rs_value("0DOC_CURRCY",ref ods_dalotab, ref ods_darow, out rs_currency); // get the unit text from the current result row get_rs_value("0SALES_UNIT",ref ods_dalotab, ref ods_darow, out rs_salesunit); // before printing the first result row print a header // with the column/field names ( InfoObject names ) if( nr_rs_rows == 0 ) {
19
// use a hard-coded offset to skip the first two // InfoObjects which are "currency" and "unit" // ( mentioned above when specifying the InfoObjects // which should be retrieved ). Print the other names // as the header line. for(nr_rs_cols=infobj_offset; nr_rs_cols < ods_dalotab.Count; nr_rs_cols++) { ods_dalorow = ods_dalotab[nr_rs_cols]; Console.Write(ods_dalorow.Infoobject.PadLeft (max_ods_col_length,' ') + " | "); } Console.WriteLine(); // print a line of dashes to make the output nicer. for(nr_rs_cols=infobj_offset; nr_rs_cols < ods_dalotab.Count-1; nr_rs_cols++) { Console.Write("".PadLeft(max_ods_col_length,'-') + "-+-"); } Console.Write("".PadLeft(max_ods_col_length,'-') + "-+"); Console.WriteLine(); } } // print the values of the result set. As every row is // sent back as a string it's necessary to use the // "ods_dalotab" structure which includes the meta data // to figure out which InfoObjects are included in the // result and what their offset and length are. This // info is used to find the correct substrings. for(nr_rs_cols=infobj_offset; nr_rs_cols < ods_dalotab.Count; nr_rs_cols++) { ods_dalorow = ods_dalotab[nr_rs_cols]; ods_col_offset = System.Convert.ToInt32(ods_dalorow.Offset); ods_col_length = System.Convert.ToInt32(ods_dalorow.Length); // the length info didn't fit for some reason for // the last column. The length was 3 and the offset // was 88. But the total length of the row string // was 90. As it's the unit string which was 'ST' // in the sample - the quick and dirty workaround was // to just correct the length for this last column. if( (ods_col_offset + ods_col_length) > ods_darow.Data.Length ) ods_col_length = ods_darow.Data.Length - ods_col_offset; // in case of the two key figures add the currency // text to the string if( ods_dalorow.Infoobject.Equals("0D_COST") || ods_dalorow.Infoobject.Equals("0D_NETVLINV") ) ods_colname = ods_darow.Data.Substring(ods_col_offset, ods_col_length ).Trim() + " " + rs_currency.Trim(); else // in case of the quantity column add the unit text
20
// to the string if( ods_dalorow.Infoobject.Equals("0D_INV_QTY")) ods_colname = ods_darow.Data.Substring(ods_col_offset, ods_col_length ).Trim() +" "+ rs_salesunit.Trim(); else ods_colname = ods_darow.Data.Substring(ods_col_offset, ods_col_length ).Trim(); Console.Write( ods_colname.Trim().PadLeft(max_ods_col_length,' ') + " | "); } // end for-loop thru all InfoObjects within one result row Console.WriteLine(); } // end for-loop thru all rows in the result set // print again a line of dashes at the end to make the output // nicer for(nr_rs_cols=infobj_offset; nr_rs_cols < ods_dalotab.Count-1; nr_rs_cols++) { Console.Write("".PadLeft(max_ods_col_length,'-') + "-+-"); } Console.Write("".PadLeft(max_ods_col_length,'-') + "-+"); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Press RETURN"); Console.ReadLine(); } // end main // method which searches in the meta data structure // for a certain InfoObject and gets the appropriate // substring ( value of the object ) from a result // row which is in fact one long string. static void get_rs_value(string inf_objname, ref BAPI6116DALOTable ods_dalotab, ref BAPI6116DA ods_darow, out string rs_value) { int i; int col_offset; int col_length; BAPI6116DALO ods_infobj; rs_value = ""; for(i=0; i<ods_dalotab.Count; i++) { ods_infobj = ods_dalotab[i]; if( ods_infobj.Infoobject.Equals(inf_objname) ) { col_offset = System.Convert.ToInt32(ods_infobj.Offset); col_length = System.Convert.ToInt32(ods_infobj.Length); // the length info didn't fit for some reason for // the last column. The length was 3 and the offset // was 88. But the total length of the row string // was 90. As it's the unit string which was 'ST'
21
// in the sample - the quick and dirty workaround was // to just correct the length for this last column. if( (col_offset + col_length) > ods_darow.Data.Length ) col_length = ods_darow.Data.Length - col_offset; rs_value = ods_darow.Data.Substring(col_offset, col_length ); } // end if – InfoObject found } // end for-loop thru all InfoObjects } // end get_rs_value() – return value for an InfoObject } // end class } // end namespace
22
Conclusion SAP .NET Connector 2.0 is a great tool which relieves developers from all the Remote
Function Call details in order to access the SAP BW BAPIs. What’s left are parameter
definitions / settings and processing the result sets. Depending on the BAPI method this
might be still some work. But it’s definitely an elegant and easy way to connect SAP BW
with the Microsoft .NET world.
It’s easier to select data from an ODSObject using the ODS BAPI than to send a MDX
query thru the OLAP BAPI. Depending on the project requirements it might be worth the
overhead and additional need of space inside BW to create an ODSObject just for the
task to access the data from an external program as the coding complexity would be
less compared to the OLAP BAPI.
Limitations The C# sample should just help to get a quick start on the topic. It cannot be used
unmodified for real application development ( e.g. no error handling included ). The
sample was tested with a simple ODSObject. It’s not guaranteed that it works 100%
correct with every ODSObject and all levels of complexity. Some changes would be
necessary anyway to work with a different ODSObject as the object name ODSDECU
as well as the InfoObject selection list and search conditions are hard-coded.
The SAP BW ODS BAPI was not made for unloading masses of data. OpenHubService
is the tool which should be used instead.
There is a difference between reporting and unloading. Imagine a BW query which
selects certain data from an ODSObject. If this data would be stored in an external
OLAP engine like Microsoft Analysis Services it’s no longer called reporting.
Whenever you extract data from the mySAP BI environment into 3rd-party target
systems your SAP BW Enterprise Data Warehouse functions as an ‘Open Hub Platform’.
Since extracting data from SAP BW by any means requires additional licensing, please
make sure to contact your SAP representative.
23
References ODSObject :
http://help.sap.com/saphelp_nw04/helpdata/en/f9/45503c242b4a67e10000000a114084/content.htm