0

行のfill_rate列を変更できるこのupsert関数があります。

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';

この関数を変更して、列引数も取ることができますか?列とテーブルを取得するように関数を変更する方法がある場合は、追加のボーナスポイント。

4

3 に答える 3

3

別の方法として、insert + update と where 句を使用して、適切なケースでのみ成功するようにすることで、関数なしでupsert を実行できます。例えば

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 固有の関数を使用することを回避できます。

于 2011-11-18T15:33:06.250 に答える
1

plsql の動的コマンドについて読みたいとします。クエリを作成して、EXECUTE を呼び出すだけです。

于 2010-06-07T18:12:44.287 に答える
0

たぶんもっと単純なアプローチで、行が少ないだけです;)

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';
于 2011-05-18T09:44:15.647 に答える