RFC Protocol Deep Dive
This comprehensive guide covers the RFC (Remote Function Call) protocol in ERPL. Learn how to read SAP tables, call function modules, and handle metadata like a pro.
RFC (Remote Function Call) is SAP's protocol for calling functions across system boundaries. It's the foundation of SAP integration and allows you to access SAP tables and execute function modules remotely.
RFC Architecture
Core RFC Functions
sap_read_table()
The primary function for reading SAP tables.
-- Basic table reading
SELECT * FROM sap_read_table('KNA1', MAX_ROWS => 100);
-- With field selection
SELECT KUNNR, NAME1, LAND1
FROM sap_read_table('KNA1', MAX_ROWS => 50);
-- With WHERE conditions
SELECT * FROM sap_read_table('VBAK', MAX_ROWS => 100)
WHERE ERDAT >= '2024-01-01';
Parameters
| Parameter | Type | Description | Example |
|---|---|---|---|
table_name | VARCHAR (positional) | SAP table name | 'KNA1' |
COLUMNS | LIST(VARCHAR) | Restrict to a subset of columns | COLUMNS => ['KUNNR', 'NAME1'] |
FILTER | VARCHAR | OpenSQL-style WHERE-fragment passed straight to RFC. Use for filters too complex to push down. | FILTER => 'LAND1 = ''DE''' |
MAX_ROWS | UINTEGER | Maximum rows to return | MAX_ROWS => 1000 |
THREADS | UINTEGER | Number of parallel RFC threads (default: 5) | THREADS => 4 |
READ_TABLE_FUNCTION | VARCHAR | Override the underlying RFC function module (e.g. /SAPDS/RFC_READ_TABLE2 for wide rows) | READ_TABLE_FUNCTION => '/SAPDS/RFC_READ_TABLE2' |
READ_TABLE_DELIMITER | VARCHAR | Delimiter RFC uses when packing rows. Override for tables whose values may contain whitespace. | `READ_TABLE_DELIMITER => ' |
SECRET | VARCHAR | Name of the DuckDB secret to authenticate with | SECRET => 'erp_prod' |
A regular SQL WHERE clause is pushed down to RFC automatically — you don't need the FILTER named parameter for simple predicates. COLUMNS is inferred from the SELECT list:
SELECT KUNNR, NAME1 FROM sap_read_table('KNA1') WHERE LAND1 = 'DE';
Reach for the named parameters when you need precise control over what RFC receives — for example, complex multi-table filters that DuckDB's optimizer can't safely lower.
RFC's underlying RFC_READ_TABLE has no server-side sort. Apply ORDER BY in DuckDB after the read; it executes client-side.
sap_rfc_invoke()
Call SAP function modules and BAPIs. Input parameters are passed as positional struct arguments after the function name — one struct per import / changing parameter the BAPI expects. DuckDB struct syntax ({'KEY': value, ...}) lets you express nested structures and tables naturally.
-- Simple function module with one import struct
SELECT trim(ECHOTEXT)
FROM sap_rfc_invoke('STFC_CONNECTION', {'REQUTEXT': 'Hello'});
-- BAPI returning a sub-table — pick it via path
SELECT *
FROM sap_rfc_invoke(
'BAPI_FLIGHT_GETLIST',
{'AIRLINE': 'LH', 'DESTINATION_FROM': {'AIRPORTID': 'FRA'}},
path => '/FLIGHT_LIST'
);
-- BAPI with nested import + path selection
SELECT *
FROM sap_rfc_invoke(
'BAPI_FLIGHT_GETDETAIL',
{'AIRLINEID': 'LH', 'CONNECTIONID': '0400', 'FLIGHTDATE': '2016-11-18'::DATE}
);
Parameters
| Parameter | Type | Description | Example |
|---|---|---|---|
function_name | VARCHAR (positional) | SAP function module / BAPI name | 'BAPI_FLIGHT_GETLIST' |
parameters... | STRUCT (positional varargs) | One struct per RFC import/changing parameter | {'AIRLINE': 'LH'} |
path | VARCHAR (named) | Optional path into the response structure — picks a sub-table of the result | path => '/FLIGHT_LIST' |
secret | VARCHAR (named) | Name of the DuckDB secret to authenticate with | secret => 'erp_prod' |
sap_rfc_describe_function()
Get detailed information about RFC function parameters.
-- Describe function parameters
SELECT * FROM sap_rfc_describe_function('BAPI_FLIGHT_GETLIST');
-- Get parameter details
SELECT
name,
import[1].name AS import_params,
export[1].name AS export_params
FROM sap_rfc_describe_function('STFC_CONNECTION');
sap_describe_fields()
Get table structure and field information.
-- Get table structure
SELECT * FROM sap_describe_fields('KNA1');
-- Get field details for specific table
SELECT
field_name,
field_type,
field_length,
decimals
FROM sap_describe_fields('VBAK');
sap_describe_references()
List all referenced tables in the SAP system.
-- List all referenced tables
SELECT * FROM sap_describe_references();
sap_rfc_show_function()
List all available RFC functions.
-- List all RFC functions
SELECT * FROM sap_rfc_show_function();
sap_rfc_show_groups()
List all RFC function groups.
-- List all function groups
SELECT * FROM sap_rfc_show_groups();
sap_show_tables()
List all available SAP tables.
-- List all tables
SELECT * FROM sap_show_tables();
Common SAP Tables
Master Data Tables
-- Customer Master Data
SELECT
KUNNR AS customer_number,
NAME1 AS customer_name,
LAND1 AS country,
REGIO AS region,
ORT01 AS city
FROM sap_read_table('KNA1', MAX_ROWS => 1000)
WHERE LAND1 = 'DE';
-- Material Master Data
SELECT
MATNR AS material_number,
MTART AS material_type,
MEINS AS base_unit,
MATKL AS material_group
FROM sap_read_table('MARA', MAX_ROWS => 1000)
WHERE MTART = 'FERT'; -- Finished goods
-- Vendor Master Data
SELECT
LIFNR AS vendor_number,
NAME1 AS vendor_name,
LAND1 AS country,
REGIO AS region
FROM sap_read_table('LFA1', MAX_ROWS => 1000);
Transaction Data Tables
-- Sales Document Header
SELECT
VBELN AS sales_document,
ERDAT AS document_date,
KUNNR AS customer,
NETWR AS net_value,
WAERK AS currency
FROM sap_read_table('VBAK', MAX_ROWS => 1000)
WHERE ERDAT >= '2024-01-01';
-- Sales Document Items
SELECT
VBELN AS sales_document,
POSNR AS item_number,
MATNR AS material,
KWMENG AS quantity,
NETWR AS net_value
FROM sap_read_table('VBAP', MAX_ROWS => 1000)
WHERE VBELN IN ('0000000001', '0000000002');
Financial Tables
-- Accounting Document Header
SELECT
BUKRS AS company_code,
BELNR AS document_number,
GJAHR AS fiscal_year,
BLART AS document_type,
BUDAT AS posting_date
FROM sap_read_table('BKPF', MAX_ROWS => 1000)
WHERE GJAHR = '2024';
-- Accounting Document Items
SELECT
BUKRS AS company_code,
BELNR AS document_number,
GJAHR AS fiscal_year,
BUZEI AS line_item,
HKONT AS gl_account,
DMBTR AS amount_in_local_currency
FROM sap_read_table('BSEG', MAX_ROWS => 1000)
WHERE HKONT LIKE '1%'; -- Asset accounts
Advanced RFC Techniques
Metadata Handling
-- Get table structure
SELECT * FROM sap_describe_fields('KNA1');
-- Get function module parameters
SELECT * FROM sap_rfc_describe_function('BAPI_CUSTOMER_GETDETAIL');
-- List all available functions
SELECT * FROM sap_rfc_show_function();
-- List function groups
SELECT * FROM sap_rfc_show_groups();
-- List all tables
SELECT * FROM sap_show_tables();
Batch Processing
-- Process multiple tables in one call
SELECT
'KNA1' AS table_name,
COUNT(*) AS record_count
FROM sap_read_table('KNA1', MAX_ROWS => 10000)
UNION ALL
SELECT
'VBAK' AS table_name,
COUNT(*) AS record_count
FROM sap_read_table('VBAK', MAX_ROWS => 10000);
Error Handling
-- Check for errors in function calls
SELECT
function_name,
return_code,
error_message
FROM sap_rfc_invoke('RFC_SYSTEM_INFO')
WHERE return_code <> '0';
Performance Optimization
Connection Pooling
-- Reuse connections for multiple queries
ATTACH 'sap://your-host:3300' AS sap_pool (
USER 'username',
PASSWORD 'password',
POOL_SIZE => 5
);
-- Multiple queries use the same connection pool
SELECT * FROM sap_read_table('KNA1', MAX_ROWS => 100);
SELECT * FROM sap_read_table('VBAK', MAX_ROWS => 100);
Parallel Processing
-- Read multiple tables in parallel
SELECT 'KNA1' AS table_name, COUNT(*) AS count
FROM sap_read_table('KNA1', MAX_ROWS => 10000)
UNION ALL
SELECT 'VBAK' AS table_name, COUNT(*) AS count
FROM sap_read_table('VBAK', MAX_ROWS => 10000)
UNION ALL
SELECT 'MARA' AS table_name, COUNT(*) AS count
FROM sap_read_table('MARA', MAX_ROWS => 10000);
Real-World Examples
Daily Sales Report
-- Extract daily sales data
WITH daily_sales AS (
SELECT
ERDAT AS sales_date,
COUNT(*) AS order_count,
SUM(NETWR) AS total_value,
AVG(NETWR) AS avg_order_value
FROM sap_read_table('VBAK', MAX_ROWS => 100000)
WHERE ERDAT >= CURRENT_DATE - INTERVAL '30' DAY
GROUP BY ERDAT
)
SELECT
sales_date,
order_count,
total_value,
avg_order_value,
ROUND(avg_order_value, 2) AS avg_order_value_rounded
FROM daily_sales
ORDER BY sales_date DESC;
Customer Analysis
-- Analyze customer distribution by country
SELECT
LAND1 AS country,
COUNT(*) AS customer_count,
COUNT(*) * 100.0 / SUM(COUNT(*)) OVER() AS percentage
FROM sap_read_table('KNA1', MAX_ROWS => 100000)
GROUP BY LAND1
ORDER BY customer_count DESC
LIMIT 10;
Material Master Analysis
-- Analyze material types and groups
SELECT
MTART AS material_type,
MATKL AS material_group,
COUNT(*) AS material_count
FROM sap_read_table('MARA', MAX_ROWS => 100000)
GROUP BY MTART, MATKL
ORDER BY material_count DESC
LIMIT 20;
Troubleshooting
Common Issues
Table Not Found
-- Check table name (case-sensitive)
-- Verify table exists in your SAP system
SELECT * FROM sap_read_table('KNA1', MAX_ROWS => 1);
Permission Denied
-- Verify RFC access rights by calling a low-privilege function
SELECT * FROM sap_rfc_invoke('RFC_SYSTEM_INFO');
Connection Timeout
Configure timeouts via the sap_rfc secret options when creating the secret:
CREATE SECRET my_sap (
TYPE sap_rfc,
ASHOST 'your-host',
SYSNR '00',
USER 'username',
PASSWD 'password',
CLIENT '100',
LANG 'EN'
);
Debugging Tips
-- Ping the SAP system (pragma — no result rows; raises on failure)
PRAGMA sap_rfc_ping;
-- Monitor query performance
EXPLAIN SELECT * FROM sap_read_table('KNA1', MAX_ROWS => 100);
-- Smoke-test the RFC pipeline
SELECT * FROM sap_rfc_invoke('RFC_SYSTEM_INFO');
For SAP Experts
This section covers RFC protocol internals for SAP Basis administrators and developers.
RFC Protocol Details
RFC uses a binary protocol over TCP/IP with the following characteristics:
- Port Range: 33xx (where xx is the instance number)
- Protocol: Binary over TCP/IP
- Authentication: Username/password or certificate-based
- Compression: Optional data compression
- Unicode: Full Unicode support
Performance Considerations
- Connection Pooling: Reuse connections to reduce overhead
- Batch Size: Optimize LIMIT parameter for your network
- Field Selection: Use FIELDS parameter to reduce data transfer
- Parallel Processing: Use multiple connections for large datasets
Security Best Practices
- Network Security: Use VPN or secure network connections
- Authentication: Use strong passwords or certificates
- Authorization: Implement proper RFC user roles
- Audit Logging: Enable RFC audit logs in SAP
Next Steps
🚀 Ready for More?
- BICS Protocol Guide - Execute SAP BW queries
- ODP Protocol Guide - Delta replication
- Function Reference - Complete API docs
🔧 Advanced Topics
- RFC Metadata Guide - Discover SAP functions and tables
- Performance Tuning - Optimize RFC calls
- Real-World Use Cases - Complete scenarios
💡 Examples
- ERPL Examples - More real-world RFC examples
- Integration with Python - Use RFC data with Pandas
Need help? Check our troubleshooting guide or browse more examples.