Search code examples
c#sap-dotnet-connector

RFC_READ_TABLE too many columns DATA_BUFFER_EXCEEDED using C#


I have two DataGridView in the main form and the first one displays data from SAP system and another displays data from Vertica DB, the Function Module I'm using is RFC_READ_TABLE, but there's an exception when calling this FM, which is, if there are too many columns in target table (more than 512 characters per row), SAP connector will return an exception:

DATA_BUFFER_EXCEEDED

Is there any other FMs or ways to retrieving data from SAP without exception?

I figured out a solution, is about split fields into several arrays and store each parts data into a datatable, then merge datatables, but I'm afraid it will cost a lot of time if the row count is too large.

screenshot of the program

Here comes my code:

RfcDestination destination = RfcDestinationManager.GetDestination(cmbAsset.Text);
            readTable = destination.Repository.CreateFunction("RFC_READ_TABLE");
            /*
             * RFC_READ_TABLE will only extract data up to 512 chars per row. 
             * If you load more data, you will get an DATA_BUFFER_EXCEEDED exception.
             */
            readTable.SetValue("query_table", table);
            readTable.SetValue("delimiter", "~");//Assigns the given string value to the element specified by the given name after converting it appropriately. 
            if (tbRowCount.Text.Trim() != string.Empty) readTable.SetValue("rowcount", tbRowCount.Text);
            t = readTable.GetTable("DATA");
            t.Clear();//Removes all rows from this table. 
            t = readTable.GetTable("FIELDS");
            t.Clear();

            if (selectedCols.Trim() != "" )
            {
                string[] field_names = selectedCols.Split(",".ToCharArray());
                if (field_names.Length > 0)
                {
                    t.Append(field_names.Length);
                    int i = 0;
                    foreach (string n in field_names)
                    {
                        t.CurrentIndex = i++;
                        t.SetValue(0, n);
                    }
                } 
            }
            t = readTable.GetTable("OPTIONS");
            t.Clear();
            t.Append(1);//Adds the specified number of rows to this table. 
            t.CurrentIndex = 0;
            t.SetValue(0, filter);//Assigns the given string value to the element specified by the given index after converting it appropriately. 

            try
            {
                readTable.Invoke(destination);
            }
            catch (Exception e)
            {
            }

Solution

  • first of all you should use BBP_READ_TABLE if it is available in your system. This one is better for much reasons. But that is not the point of your question. In RFC_READ_TABLE you have two Imports ROWCOUNT and ROWSKIPS. You have to use them.

    I would recommend you a rowcount between 30.000 and 60.000. So you have to execute the RFC several times and each time you increment your ROWSKIPS. First loop: ROWCOUNT=30000 AND ROWSKIPS = 0, Second Loop: ROWCOUNT=30000 AND ROWSKIPS=30000 and so on...

    Also be careful of float-fields when using the old RFC_READ_TABLE. There is one in table LIPS. This RFC has problems with them.