Expanding on the usual INSERT OR UPDATE conondrum
I have a function that serves normal UPDATE OR INSERT, and it looks like this:
CREATE OR REPLACE FUNCTION updateslave ( varchar(7), smallint ) RETURNS void AS
$$
BEGIN
LOOP
UPDATE consist SET
master = $1,
time = now() WHERE slave = $2;
IF found THEN
RETURN;
END IF;
BEGIN
INSERT INTO consist(master, slave, time) VALUES ( $1, $2, now() );
RETURN;
EXCEPTION WHEN unique_violation THEN
-- do nothing, then loop and retry
END;
END LOOP;
END;
##
LANGUAGE plpgsql;
Now, the issue is that i’m trying to rewrite it for a similar operation in a different, table. However, the difference is that in this other table there is no single unique column, but the combination of two columns only exists in one row. Is it possible to declare unique_violation based on the combination of two columns instead?
For the sake of keeping examples simple, let’s assume that the table looks exactly the same as the one i use the above function for, but with master and slave being the two columns that together produce uniqueness:
Column | Type | Modifiers | Storage | Description
--------+-----------------------------+----------------------------------------------+----------+-------------
master | character varying(7) | not null default 'unused'::character varying | extended |
slave | smallint | not null | plain |
time | timestamp without time zone | default now() | plain |
The best approach is to define a unique constraint on the table, that way no matter how the update happens, ie if your proc is used or not, everything is OK.
The easiest way to do that is to create a unique index over the two columns:
You can also alter the table to add a unique constraint, but there’s not much difference.