Db2 SQLCODE

SQLCODE -603: Duplicate rows block a unique index

SQLCODE -603 (SQLSTATE 23515) means CREATE UNIQUE INDEX failed because the table already holds rows with the same values in the index columns. Db2 can't build a unique index over duplicates.

Other names for this code

Also written as SQL -603, SQLCODE=-603, SQLCODE = -603, db2 -603, sqlstate 23515, SQL0603N, unique index cannot be created because the table contains rows which are duplicates.

What it means

A unique index allows each key value only once. When you create one on a table that already has data, Db2 reads the rows to build the index. If two rows share the same key, it stops, rejects the CREATE with -603 and no index is created.

The duplicates got in because nothing enforced uniqueness before. The table had no unique index on those columns, or a different one.

Nulls count. In a plain unique index, two rows with null in the key columns count as duplicates. If you need many nulls but unique non-null values, Db2 for z/OS offers CREATE UNIQUE WHERE NOT NULL INDEX.

On Db2 releases with temporal tables, the message also mentions periods. A unique index that includes BUSINESS_TIME WITHOUT OVERLAPS fails the same way when rows for the same key have overlapping business time periods.

Common causes

  • Data was loaded or copied into the table before the unique index existed.
  • The table is getting a primary key or unique constraint late in its life and the data was never checked.
  • Several rows have null in the key columns, and the index is a plain unique index.
  • Batch reruns inserted the same rows twice while no unique index stopped them.
  • For a temporal table, business time periods overlap for the same key.

How to find the problem

  1. List the duplicate keys with SELECT CUST_NO, COUNT(*) FROM PROD.CUSTOMER GROUP BY CUST_NO HAVING COUNT(*) > 1, using all the index columns in the GROUP BY.
  2. Count rows with nulls in the key columns separately, since they also count as duplicates.
  3. Select the full duplicate rows and compare them. Exact copies point at a double load. Rows that differ point at a key that isn't really unique.

How to fix it

  • If the duplicates are mistakes, delete or merge them, then create the index again.
  • If the duplicates are valid data, the columns aren't a unique key. Create a non-unique index instead, or add a column that makes the key unique.
  • If only nulls repeat, use CREATE UNIQUE WHERE NOT NULL INDEX.
  • After the index exists, Db2 enforces it, and later duplicates fail with -803 at INSERT or UPDATE time.

What it looks like

DSNT408I SQLCODE = -603, ERROR:  A UNIQUE INDEX CANNOT BE CREATED BECAUSE THE TABLE CONTAINS ROWS WHICH ARE DUPLICATES WITH RESPECT TO THE VALUES OF THE IDENTIFIED COLUMNS AND PERIODS
DSNT418I SQLSTATE   = 23515 SQLSTATE RETURN CODE

IBM documentation

IBM documentation: -603. Use the documentation for your installed release.

Report a correction to WND Software.

Questions

What is the difference between -603 and -803?

-603 happens when you create a unique index on data that already has duplicates. -803 happens when an index already exists and an INSERT or UPDATE would add a duplicate.

Do nulls count as duplicates?

In a plain unique index, yes. CREATE UNIQUE WHERE NOT NULL INDEX lets many rows have null in the key.

Is -603 the same on Db2 for LUW?

Yes. Db2 for LUW reports SQL0603N with SQLSTATE 23515.