Динамический upsert в postgresql - PullRequest
0 голосов
/ 07 июня 2010

У меня есть эта функция upsert, которая позволяет мне изменять столбец fill_rate строки.

CREATE FUNCTION upsert_fillrate_alarming(integer, boolean) RETURNS VOID AS '
DECLARE
    num ALIAS FOR $1;
    dat ALIAS FOR $2;

BEGIN
    LOOP
        -- First try to update.
    UPDATE alarming SET fill_rate = dat WHERE equipid = num;
    IF FOUND THEN
        RETURN;
    END IF;
    -- Since its not there we try to insert the key
    -- Notice if we had a concurent key insertion we would error
    BEGIN
        INSERT INTO alarming (equipid, fill_rate) VALUES (num, dat);
        RETURN;
    EXCEPTION WHEN unique_violation THEN
        -- Loop and try the update again
    END;
    END LOOP;
END;
' LANGUAGE 'plpgsql';

Можно ли изменить эту функцию, чтобы она также принимала аргумент столбца?Дополнительные бонусные баллы, если есть способ изменить функцию, чтобы взять столбец и таблицу.

Ответы [ 3 ]

3 голосов
/ 18 ноября 2011

В качестве альтернативного подхода вы можете выполнить upsert без функции, используя вставки + update с предложениями where, чтобы сделать их успешными только в правильном случае. Э.Г.

update mytable set col1='value1' where (col2 = 'myId');
insert into mytable select 'value1', 'myId' where not exists (select 1 from mytable where col2='myId');

Что позволит избежать использования множества специальных функций postgres.

1 голос
/ 07 июня 2010

Вы хотите прочитать о динамических командах в plsql . Просто создайте свой запрос и вызовите EXECUTE.

0 голосов
/ 18 мая 2011

Возможно, более простой подход, просто меньше строк;)

CREATE OR REPLACE FUNCTION upsert_tableName(arg1 type, arg2 type) RETURNS VOID AS $$
DECLARE
BEGIN
    UPDATE tableName SET col1 = value WHERE colX = arg1 and colY = arg2;
    IF NOT FOUND THEN
    INSERT INTO tableName values (value, arg1, arg2);
    END IF;
END;
$$ LANGUAGE 'plpgsql';
...