Insert, on duplicate update in PostgreSQL?

前端 未结 16 2285
别那么骄傲
别那么骄傲 2020-11-21 04:52

Several months ago I learned from an answer on Stack Overflow how to perform multiple updates at once in MySQL using the following syntax:

INSERT INTO table          


        
16条回答
  •  醉话见心
    2020-11-21 05:31

    Edit: This does not work as expected. Unlike the accepted answer, this produces unique key violations when two processes repeatedly call upsert_foo concurrently.

    Eureka! I figured out a way to do it in one query: use UPDATE ... RETURNING to test if any rows were affected:

    CREATE TABLE foo (k INT PRIMARY KEY, v TEXT);
    
    CREATE FUNCTION update_foo(k INT, v TEXT)
    RETURNS SETOF INT AS $$
        UPDATE foo SET v = $2 WHERE k = $1 RETURNING $1
    $$ LANGUAGE sql;
    
    CREATE FUNCTION upsert_foo(k INT, v TEXT)
    RETURNS VOID AS $$
        INSERT INTO foo
            SELECT $1, $2
            WHERE NOT EXISTS (SELECT update_foo($1, $2))
    $$ LANGUAGE sql;
    

    The UPDATE has to be done in a separate procedure because, unfortunately, this is a syntax error:

    ... WHERE NOT EXISTS (UPDATE ...)
    

    Now it works as desired:

    SELECT upsert_foo(1, 'hi');
    SELECT upsert_foo(1, 'bye');
    SELECT upsert_foo(3, 'hi');
    SELECT upsert_foo(3, 'bye');
    

提交回复
热议问题