Tell me more ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

I've read about different UPSERT implementations in PostgreSQL, but all of these solutions are relatively old or relatively exotic (using writeable CTE, for example).

And I'm just not a psql expert at all to find out immediately, whether these solutions are old because they are well recommended or they are (well, almost all of them are) just toy examples not appropriate to production use.

So my question is following. Regarding to the fact that it is year 2012, what is the most common, most thread-safe way to implement UPSERT in PostgreSQL?

share|improve this question
1  
if you're using ruby, you might try the upsert ruby library - a python version is forthcoming – Seamus Abshere Sep 10 '12 at 21:57

1 Answer

up vote 3 down vote accepted

The preferred method according a similar StackOverflow question is currently the following:

CREATE TABLE db (a INT PRIMARY KEY, b TEXT);

CREATE FUNCTION merge_db(key INT, data TEXT) RETURNS VOID AS
$$
BEGIN
    LOOP
        -- first try to update the key
        UPDATE db SET b = data WHERE a = key;
        IF found THEN
            RETURN;
        END IF;
        -- not there, so try to insert the key
        -- if someone else inserts the same key concurrently,
        -- we could get a unique-key failure
        BEGIN
            INSERT INTO db(a,b) VALUES (key, data);
            RETURN;
        EXCEPTION WHEN unique_violation THEN
            -- do nothing, and loop to try the UPDATE again
        END;
    END LOOP;
END;
$$
LANGUAGE plpgsql;

SELECT merge_db(1, 'david');
SELECT merge_db(1, 'dennis');
share|improve this answer
3  
I'd rather use a writeable CTE: stackoverflow.com/a/8702291/330315 – a_horse_with_no_name Feb 21 '12 at 11:33
What's the advantage of a writable CTE vs a function? – François Beausoleil Feb 21 '12 at 13:23
@François I'm sorry, I don't know enough about this to comment. Perhaps a_horse_with_no_name or someone else can post an answer. – Leigh Riffel Feb 21 '12 at 14:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.