SAPSQL_ARRAY_INSERT_DUPREC — Array Insert Duplicate Record Dump
SAPSQL_ARRAY_INSERT_DUPREC is a runtime error raised when an ABAP INSERT statement working from an internal table (an array insert) tries to write a row whose primary key already exists, either in the database table or duplicated within the internal table itself. It is an unhandled CX_SY_OPEN_SQL_DB exception, and the fix is almost always in program logic, not in Basis.
This page covers the SAPSQL_ARRAY_INSERT_DUPREC short dump, which fires when a mass INSERT from an internal table collides with an existing primary key. It walks through the realistic causes ranked by frequency, what to read in the ST22 dump to tell them apart, and why simply catching the exception or deleting the conflicting row is the wrong first move.
Published 16 Sept 2026· 1,270 words
What the dump means
An array insert is a single INSERT statement executed against a database table using an internal table as the source, so all rows are sent to the database in one operation instead of row by row. The database rejects the whole operation if any row's key already exists, and the open SQL layer raises CX_SY_OPEN_SQL_DB with the DUPREC subclass rather than letting the program continue with a return code. Because this is a class-based exception and most programs still rely on checking sy-subrc after INSERT, the exception goes uncaught and the runtime terminates with this dump. The message tells which table and which statement, but not why the key already existed, which is the actual investigation.
Root causes that actually produce it
- Duplicate keys inside the source internal table itself: the internal table was built by a loop, join, or BAPI collection step that produced two or more rows with the same key fields, and no SORT plus DELETE ADJACENT DUPLICATES or COLLECT step ran before the insert. This is the single most common cause and is purely a coding defect.
- Reprocessing already-posted data: a batch job, interface, or IDoc processing report is rerun after a partial failure or manual restart without first deleting or filtering out the records it already wrote in the previous run. The second run tries to insert rows that are legitimately already there.
- Race condition between parallel processes: two background jobs, dialog sessions, or parallel work processes generate and insert the same key at nearly the same moment because there is no ENQUEUE lock or check-before-insert logic serializing them. Common in custom number range assignment or custom master data creation programs.
- Number range or key generation defect: a custom key-generation routine reuses a number because a buffer was reset, a rollback discarded a commit that should have advanced the counter, or two systems generating keys for the same table were not synchronized.
- Table structure or key change: a transport added or removed a field from the primary key of a custom or append-enhanced table, so combinations that used to be unique now collide, and existing load programs were never adjusted to the new key.
- Test or migration data reload: a data load or LSMW-style program is executed twice against the same target without a preceding delete, common in cutover rehearsals.
What to inspect in ST22
- Error class and category at the top of the dump: confirms CX_SY_OPEN_SQL_DB and the duplicate-record subclass rather than a generic SQL error, ruling out authorization or syntax problems.
- The 'What happened' and 'Trigger location' sections: give the exact program, include, and line number of the INSERT statement, and the database table name being written.
- Source code extract: shows whether the statement is INSERT itab_name INTO TABLE dbtab or similar, and whether a SORT or dedup step exists just above it.
- Container / active variables: display the internal table content at the point of failure; look for repeated key values across rows, which confirms an in-memory duplicate rather than a database collision.
- Call stack: identifies whether this ran under a background job (check SM37 for the job and prior runs), an IDoc inbound function (check WE02 or WE05), or a manual transaction.
- System fields sy-subrc and sy-dbcnt shown in the dump context: sy-dbcnt of zero at the point of failure indicates no rows were committed from that particular array insert, useful for deciding whether a clean rerun is safe.
- Follow up in SE11 or SE16 on the target table's primary key definition to confirm which fields actually define uniqueness, especially after recent transports.
Resolution path
If the internal table contains duplicates in memory, fix the source program to SORT the table by the key fields and run DELETE ADJACENT DUPLICATES, or switch the build logic to COLLECT or a hashed table with unique key, before the INSERT; this requires a code change and a transport. If the cause is a rerun of a job that already wrote part of its data, do not touch the code first: check with the functional owner whether the already-inserted rows are correct, then either delete the specific already-processed keys through the proper business transaction or add a restart-safety check to the program that skips or updates existing keys, which again needs a change request. If a race condition between parallel processes is confirmed, add an ENQUEUE lock or a SELECT SINGLE FOR UPDATE style check ahead of the insert, or reschedule the jobs to run serially as an interim workaround while the code fix is built and transported. If a key generation defect is confirmed, escalate the number range logic to whoever owns that custom development; this is a design defect, not a data cleanup. If the table's key changed, treat it as a data model issue for the functional team before any code touches the program.
The fix people try first (and why it fails)
The reflex is to wrap the INSERT in a TRY/CATCH for CX_SY_OPEN_SQL_DB, or switch to INSERT with an implicit ignore of the duplicate error, and move on once the dump stops appearing. This silences the symptom without explaining why the duplicate existed, and it silently drops the conflicting rows from the array insert on most database platforms, meaning some records that were supposed to be posted never make it into the table. The failure resurfaces weeks later as a reconciliation gap, missing accounting documents, or missing master data that nobody connects back to this dump because the program now runs cleanly.
Prevention
Make deduplication of the source internal table a mandatory review checkpoint for any program that performs an array insert, especially interface and mass-load programs: SORT plus DELETE ADJACENT DUPLICATES immediately before the statement, or build the table as a sorted or hashed type with a unique key from the start. For programs that can be rerun after failure, design them to be restart-safe by checking existing keys or using MODIFY instead of INSERT where the business logic allows an update-or-insert pattern. For concurrent key generation, use proper locking rather than relying on timing.
Whose problem this is
This is an ABAP development issue in almost every case, since the missing dedup logic, missing lock, or restart-unsafe design lives in program code. Basis involvement is limited to cases where a number range buffer or lock table sizing genuinely contributed. The handover note should state the table name and key fields involved, the program and line from the dump, whether the job is safe to simply rerun or needs data cleanup first, and whether any rows were silently lost if the program had error handling around the insert.
Related SAP objects
Reviewed pages this object connects to in the ERPClimb knowledge graph.
Source: ERPClimb — https://erpclimb.com/sap-abap-dumps/sapsql-array-insert-duprecERPClimb is an independent platform and is not affiliated with SAP SE. Reference pages are written and reviewed by SAP consultants for learning and troubleshooting.