Reputation: 302
What I'm looking for is behavior like what you would observe when adding a constraint (e.g., unique) to an existing table, validating it against the existing data, then removing the constraint. I don't want the constraint to persist on the table, I just want to express it, validate it on existing data, then move on (or raise an exception of the check fails); Does Postgresql (9.2) support a way to do this sort of thing directly?
Upvotes: 0
Views: 394
Reputation: 125434
Create the constraint:
alter table t
add constraint the_pk primary key (user_id);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "the_pk" for table "t"
ERROR: could not create unique index "the_pk"
DETAIL: Key (user_id)=(1) is duplicated.
If there was no error drop it:
alter table t
drop constraint the_pk;
If you don't want to persist it even for some time then do it inside a transaction:
begin;
alter table t
add constraint the_pk primary key (user_id);
Once satisfied roll the transaction back:
rollback;
Upvotes: 2
Reputation: 657982
IF EXISTS
is generally simpler and faster for this purpose in plpgsql:
DO
$$
BEGIN
IF EXISTS (SELECT 1 FROM tbl GROUP BY tbl_id HAVING count(*) > 1) THEN
RAISE EXCEPTION 'Duplicate "tbl_id" in table "tbl"!';
END IF;
END
$$ LANGUAGE plpgsql;
Upvotes: 1
Reputation: 324751
Setup:
CREATE TABLE testu ( id integer );
INSERT INTO testu SELECT generate_series(1,100);
INSERT INTO testu VALUES (1),(10),(20);
Demo query to find possible problem rows:
regress=> select id, count(id) FROM testu GROUP BY id HAVING count(id) > 1;
id | count
----+-------
20 | 2
1 | 2
10 | 2
(3 rows)
Wrap it in DO
block:
DO
$$
BEGIN
PERFORM id FROM testu GROUP BY id HAVING count(id) > 1 LIMIT 1;
IF FOUND THEN
RAISE EXCEPTION 'One or more duplicate IDs in table testu';
END IF;
END;
$$ LANGUAGE plpgsql;
If you want to report the individual colliding IDs you might do that by building a string from the results of the query, by looping over the results and raising NOTICE
s, etc. Lots of options. I'll leave that as an exercise to you, the reader, with the PL/PgSQL documentation.
Upvotes: 1