CX_SY_OPEN_SQL_DB¶
Raised for Open SQL database errors, including duplicate key violations.
Purpose¶
CX_SY_OPEN_SQL_DB is the class-based wrapper for database-level errors that occur during Open SQL DML statements (INSERT, UPDATE, MODIFY, DELETE). Introduced in ABAP 7.40, it replaces the older SY-SUBRC = 4 / SY-DBCNT pattern for bulk DML and provides structured error information instead of a short dump.
Inheritance chain:
CX_SY_OPEN_SQL_DB → CX_SY_OPEN_SQL → CX_DYNAMIC_CHECK → CX_ROOT
Before ABAP 7.40
On releases below 7.40, a duplicate key on INSERT sets SY-SUBRC = 4 and does not raise an exception. The class-based approach only applies when the statement is written in strict 7.40+ syntax.
How to catch¶
INSERT with duplicate-key handling¶
TRY.
INSERT ztable FROM TABLE @lt_records.
CATCH cx_sy_open_sql_db INTO DATA(lx_db).
" If the exception is raised, NO rows from lt_records were written.
" The INSERT statement is atomic — it is all-or-nothing.
MESSAGE lx_db->get_text( ) TYPE 'I'.
ENDTRY.
Atomicity: zero rows on exception
When CX_SY_OPEN_SQL_DB is caught, the entire DML statement has been rolled back at the database level. No partial inserts/updates exist. Do not attempt to query how many rows succeeded — the answer is zero.
UPDATE / DELETE¶
TRY.
UPDATE ztable
SET status = 'X'
WHERE bukrs = @lv_bukrs.
CATCH cx_sy_open_sql_db INTO DATA(lx).
MESSAGE lx->get_text( ) TYPE 'E'.
ENDTRY.
Logging the error and re-raising¶
Use get_text( ) for a short display message and get_longtext( ) for the full technical description — useful for application logs:
TRY.
INSERT ztransaction FROM TABLE @lt_records.
CATCH cx_sy_open_sql_db INTO DATA(lx).
" Log the full technical detail
MESSAGE lx->get_longtext( ) TYPE 'I'.
" Re-raise so the caller can decide what to do
RAISE EXCEPTION lx.
ENDTRY.
More than just duplicates
CX_SY_OPEN_SQL_DB fires for any database error, not only duplicate keys. Common triggers include:
- Deadlocks (two sessions locking each other)
- Lock wait timeouts
- Database connection loss
- Constraint violations other than primary key (foreign key, check constraint)
- Tablespace / quota exhaustion
Always log get_longtext( ) before assuming the cause is a duplicate.
Common scenarios¶
Bulk load from file with duplicate tolerance¶
SPLIT lv_line AT '|' INTO TABLE lt_fields.
" ... build lt_records from lt_fields ...
TRY.
INSERT ztransaction FROM TABLE @lt_records.
CATCH cx_sy_open_sql_db INTO DATA(lx).
" Bulk insert failed — fall back to row-by-row with MODIFY
LOOP AT lt_records INTO DATA(ls_rec).
MODIFY ztransaction FROM ls_rec.
ENDLOOP.
ENDTRY.
Background job with structured error reporting¶
TRY.
DELETE FROM zlog WHERE timestamp < @lv_cutoff.
CATCH cx_sy_open_sql_db INTO DATA(lx).
MESSAGE lx->get_text( ) TYPE 'E'.
ENDTRY.
See also¶
- SAPSQL_ARRAY_INSERT_DUPREC — short dump analysis for SAPSQL_ARRAY_INSERT_DUPREC