Skip to content

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_DBCX_SY_OPEN_SQLCX_DYNAMIC_CHECKCX_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

Comments