简体   繁体   中英

Unique index - unique value in col1 OR col2

I have two columns in table tab : col1 and col2 . I want make them unique in such way that if value X is inserted into col1 then it should no be present in ANY row neither in col1 nor in col2 (and vice versa). So in fact I want to treat both col1 and col2 as same column (according to uniqueness). It seems to be simple but I can't figure out how to set proper index(es)...

You can use a rule or a trigger. For convenience you need first a simple function which check if a value already exists:

CREATE OR REPLACE FUNCTION check_value_exists(val ANYELEMENT) returns boolean as $$
select val IN  (select col1 from tab union select col2 from tab) 
$$
LANGUAGE sql;

And a rule could be so:

create or replace rule check_uniqueness as on insert to tab where (check_value_exists(NEW.col1) OR check_value_exists(NEW.col2)) DO INSTEAD NOTHING;

Now if you try to insert a value which already exists, nothing will be inserted (DO INSTEAD NOTHING).

If you want better handle the case if values are already present (ie raise exceptions or warnings or something else), you probably better use a trigger (a little more code but more powerful):

CREATE OR REPLACE FUNCTION check_uniqueness() RETURNS TRIGGER AS $$
BEGIN
  IF (check_value_exists(NEW.col1) OR check_value_exists(NEW.col2)) THEN
     RAISE EXCEPTION 'Value % or % already exists',NEW.col1,NEW.col2;
  END IF;
  return NEW;
  END;
$$LANGUAGE  plpgsql;


CREATE TRIGGER check_uniqueness_trigger BEFORE INSERT ON tab FOR EACH ROW EXECUTE PROCEDURE check_uniqueness();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM