postgresqlconstraintssql-function

Add constraint with CHECK on existing table with data


I want to add a constraint on an existing table. Below is my SQL statement.

CREATE OR REPLACE FUNCTION constraintFunction(uuid, date)
RETURNS integer AS $total$
declare
    total integer;
begin
    select count(*) into total FROM table1 WHERE foreign_key_id= $1 AND dt= $2 and status ='A';
   RETURN total;
END;
$total$ LANGUAGE plpgsql;

ALTER TABLE table1
  ADD CONSTRAINT constraint1 CHECK ((constraintFunction(table1.foreign_key_id, table1.dt) < 1));

I get this error below when I execute the SQL statements.

SQL Error [23514]: ERROR: check constraint "constraint1" is violated by some row

I have some records in table1. When I deleted the data with status = "A", the SQL statement will work perfectly.

Is there any way that I can add the constraint without deleting my existing data in DB?


Solution

  • A check constraint is not the solution here, as the doc explicitly warn about not looking at other rows/tables, and to use an immutable function (always the same output for a given input, which can be cached)

    Your validation fail because the said constraint asks that there is no row with the given value... if rows exist, the constraint fail, so you would want to exclude the rows having the same ID as the current row being validated.

    That being said, a unique partial index is really what is needed here.

    create unique index idx_A on table1 (foreign_key_id, dt) where status ='A';