将表数组作为参数传递给 postgresql 中的 upsert 函数

ind*_*ago 1 postgresql functions postgresql-9.1 array upsert

我有一个运行良好的 UPSERT 函数,但我批量更新和插入记录,可以修改此函数,以便我将所有记录作为数组传递给此函数,然后它将作为一个事务一次性插入/更新所有记录? 如果记录号 x 失败,它应该回滚撤消在 x 之前插入/更新的任何记录?这是我的 upsert 函数:

CREATE OR REPLACE FUNCTION save_weights(rec tbl_weightment)
  RETURNS text AS
$BODY$
DECLARE 
myoutput text :='Nothing has occured';
BEGIN

    update tbl_weightment set 
    vname=rec.vname,
    iquality=rec.iquality,
    vhooks=rec.vhooks,
    tstamp=rec.tstamp
    vtare=rec.vtare,
    vgross=rec.vgross     
    WHERE id=rec.id;

    IF FOUND THEN
        myoutput:= 'Record successfully updated';
        RETURN myoutput;
    END IF;

    BEGIN
        INSERT INTO tbl_weightment SELECT(rec).*;
        myoutput:= 'Record successfully added';           
    END;
 RETURN myoutput;

    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
Run Code Online (Sandbox Code Playgroud)

这个功能可以修改成这样save_weights(rec tbl_weightment[])吗??任何帮助将不胜感激

dez*_*zso 5

我想是的。尚未尝试使用实际的 INSERT 或 UPDATE,但此功能有效:

CREATE TABLE a (id integer);

CREATE OR REPLACE FUNCTION arraytest2(rec a[]) RETURNS SETOF integer AS
$body$
SELECT b.*
FROM unnest($1) b;
$body$
LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)

这样你就可以把你的 INSERT 语句写成

INSERT INTO tbl_weightment 
SELECT (r).*
FROM unnest(rec) r;
Run Code Online (Sandbox Code Playgroud)

并更新为

UPDATE tbl_weightment 
SET 
    vname = r.vname,
    iquality = r.iquality,
    vhooks = r.vhooks,
    tstamp = r.tstamp
    vtare = r.vtare,
    vgross = r.vgross 
FROM unnest(rec) r
WHERE id=rec.id;
Run Code Online (Sandbox Code Playgroud)