Full questions with full answers β no sign-in required.
mediumOpen SQL
1. After executing a SELECT statement in Open SQL, your SY-SUBRC is 0 but the result set is logically empty (e.g., all rows filtered out in your application logic). How does this differ from a true database 'no rows found' scenario, and what debugging approach would you take?
SY-SUBRC = 0 after SELECT means the query executed successfully and at least one row was returned by the database. If your application logic then filters all rows away, SY-SUBRC remains 0 because it reflects database execution status, not application filtering. True 'no rows found' occurs when the WHERE clause matches zero rows at the database level (SY-SUBRC = 4). To debug, inspect the actual fetched row count before and after application filtering. Use ST05 (SQL Trace) to see the exact SELECT statement and row count returned by the database. Alternatively, capture the internal table's line count immediately after SELECT (DESCRIBE TABLE it LINES lv_count) to see how many rows the database actually returned before application filtering. Check your WHERE clause logic to ensure it's pushing the right filters down to the database rather than fetching excessive rows in ABAP.
hardEnhancements
2. Explain the execution sequence when multiple customer exits and user exits are active for the same function. Can this create problems? Provide a real scenario.
There is no generic SAP rule that all customer exits run first or that numbered EXIT_* function modules define a universal sequence. Each enhancement runs where the standard program calls it. To determine the real order, inspect the standard source and call stack, set breakpoints in every relevant user exit, function exit and BAdI, then execute the same business scenario. Multiple enhancements can conflict when they modify the same structures, assume different intermediate states, issue contradictory messages or perform duplicate database access. Prevent this by assigning one responsibility to each enhancement, centralizing shared logic in reusable classes, documenting dependencies and avoiding direct updates. If order is business-critical but not contractually guaranteed by SAP, redesign to remove that dependency.
hardOpen SQL
3. A report queries purchase orders from multiple vendors. You have a list of 800 vendor IDs and need to fetch orders for all of them efficiently. Compare FOR ALL ENTRIES vs. JOIN approaches and recommend based on your experience.
FOR ALL ENTRIES approach: SELECT * FROM orders INTO TABLE lt_orders FOR ALL ENTRIES IN lt_vendors WHERE vendor_id = lt_vendors-vendor_id. Results in 2 queries if driver table (lt_vendors) is not empty. If lt_vendors is empty, the FOR ALL ENTRIES condition can be ignored and the query may return a much larger result set than intended, so handle it separately with IF lt_vendors IS NOT EMPTY. JOIN approach: SELECT o~*, v~vendor_name FROM orders AS o INNER JOIN vendors AS v ON o~vendor_id = v~vendor_id INTO TABLE lt_result WHERE o~vendor_id IN @lt_vendor_ids. Results in 1 query. FOR ALL ENTRIES is beneficial if: orders table has few columns or selective field fetch is preferred, or if vendors table is very large (JOIN might be inefficient). JOIN is preferred if: relationship is well-defined, need vendor details in one fetch, and both tables have good indexes on join fields. In S/4HANA, JOINs are often optimized by the database and CDS Views; prefer JOIN if semantic. For 800 vendors, either works, but JOIN (1 query) outperforms FOR ALL ENTRIES (2 queries) in network latency and database connection overhead. Always run ST05 on both approaches with actual data volume to confirm.
mediumWorkflow
4. Explain the core building blocks of SAP Business Workflow architecture and how they interact to execute a workflow instance.
SAP Business Workflow is built on several key components that work together. The Business Object Repository (BOR) or ABAP classes (via BOR-compatible interfaces) define business objects with their key fields, attributes, methods, and events - these represent the real-world entities like Purchase Requisition or Leave Request. Workflow Templates (transaction SWDD/PFTC) contain the workflow definition built from steps such as Activity steps (calling BOR methods or tasks), Decision steps (user decisions), Condition steps (branching logic), and Fork/Join for parallel processing. Tasks (TS) are single-step tasks that wrap a BOR method or class method call, while Workflow Templates (WS) orchestrate multiple tasks. The Workflow Runtime System, exposed largely through the Workflow Engine, manages the actual execution, maintaining Work Items (business objects representing activities to be performed) and Work Item Containers holding runtime data. Agent Determination Rules define who gets work items in their inbox, using either responsibility rules, role resolution, or organizational assignment via HR org structure. Events (raised by application programs via SWE_EVENT_CREATE or ABAP class events) trigger the start of workflows or activate waiting steps, linked through the Event Linkage table maintained via SWETYPV. Container operations pass data between steps using bindings. Together, when a business event fires, the linkage triggers workflow start, the engine interprets the definition, resolves agents, creates work items, and processes them through SAP Business Workplace or the Fiori My Inbox, tracking status via the workflow log (SWI1) until completion.
hardOpen SQL
5. A SELECT statement into an internal table takes 30 seconds. After analyzing the code, you realize the WHERE clause doesn't use any indexed fields, and a full table scan is occurring. How would you refactor this, and what tools would you use to verify improvement?
Root cause: full table scan on a large table due to WHERE clause not matching available indices. Refactoring steps: (1) Analyze indices on the table (SE11 > Indices tab) to understand what indices exist. (2) Review WHERE clause fields and rewrite to use leading index fields if possible. Example: old WHERE status = 'OPEN', new WHERE created_date BETWEEN @v_start AND @v_end AND status = 'OPEN' (if index exists on created_date). (3) If no suitable index exists, propose one through normal SE11/index governance on WHERE clause fields in the correct order. (4) Use ST05 to baseline current performance (full table scan, execution time). (5) Deploy refactored code with new WHERE clause or index. (6) Re-run ST05 to compare: access pattern should change from Full Table Scan to Index Access, execution time should drop significantly. (7) If results are still poor, apply PACKAGE SIZE to batch-fetch or consider CDS View. Expected outcome: 30 seconds β 2-3 seconds with proper index. Before/after ST05 comparison is the proof point. Document the index creation and WHERE clause refactoring in your code comments for maintenance.
hardOpen SQL
6. Design a robust error handling and monitoring strategy for a production Open SQL batch job that processes 10 million rows. Include recovery, logging, and performance tracking.
A production Open SQL batch job processing 10 million rows needs controlled package design, audit logging, and restartability. First, define package boundaries by key range, date range, or a checkpoint sequence so each package can be selected, processed, written, and committed independently. Use TRY...CATCH around database and processing sections, catching relevant exceptions such as cx_sy_open_sql_db and logging the technical message, package key range, row counts, user, timestamp, and job name. After each successful package, write a checkpoint record and COMMIT WORK so restart can begin from the last completed package. Do not commit inside an active database cursor; ensure the package SELECT has completed before commit. Monitoring should include SM37 job logs, ST05 for SQL traces during performance tests, SM50 for active work process observation, SM12 for lock/enqueue issues if updates are involved, ST22 for dumps, and an application log/custom log table for business status. Track rows per second and package duration, and alert if the rate drops below threshold. Recovery should be idempotent: re-running a package should not duplicate records, either by using unique keys/upsert logic, processed flags, or a staging table with status.