Postgresql,根据具体情况更新或插入

时间:2016-07-17 19:09:55

标签: postgresql case-when

当我单独运行并且没有事务时,更新和插入语句有效...

但是我喜欢在事务中以给定的顺序执行它们并且每次都获得RETURNING值 - 无论它是否插入或更新 - 我该怎么做?

BEGIN;
UPDATE globaldata SET valuetext=(SELECT (CAST(coalesce(valuetext, '0') AS integer) + 1) FROM globaldata WHERE keyname='bb') WHERE keyname='bb' RETURNING valuetext;
INSERT INTO globaldata (keyname, valuetext)SELECT 'bb', '1' WHERE NOT EXISTS (SELECT 1 FROM globaldata WHERE keyname='bb') RETURNING valuetext;
COMMIT;

我试图用CASE包装更新并插入语句然后......但是我没有成功......

我喜欢做类似的事情:

BEGIN;
CASE
    WHEN (select count(id) from globaldata where keyname='bb') > 0 THEN
UPDATE globaldata SET valuetext=(SELECT (CAST(coalesce(valuetext, '0') AS integer) + 1) FROM globaldata WHERE keyname='bb') WHERE keyname='bb' RETURNING valuetext;
ELSE
    INSERT INTO globaldata (keyname, valuetext)SELECT 'bb', '1' WHERE NOT EXISTS (SELECT 1 FROM globaldata WHERE keyname='bb') RETURNING valuetext;
END;
COMMIT;

2 个答案:

答案 0 :(得分:0)

尝试使用DO

已更新

       do 
        $$
        declare _valuetext text;
        BEGIN
        if
            (select count(id) from globaldata where keyname='bb') > 0 THEN
        UPDATE globaldata SET valuetext=(SELECT (CAST(coalesce(valuetext, '0') AS integer) + 1) FROM globaldata WHERE keyname='bb') WHERE keyname='bb' RETURNING valuetext into _valuetext
    ;
raise info '%','_valuetext is '||_valuetext;
        ELSE
            INSERT INTO globaldata (keyname, valuetext)SELECT 'bb', '1' WHERE NOT EXISTS (SELECT 1 FROM globaldata WHERE keyname='bb') 
    RETURNING valuetext  into _valuetext
    ;
raise info '%','_valuetext is '||_valuetext;
         end if;
            END;
            $$
            ;

答案 1 :(得分:0)

我一直想做到这一点,在调查并稍微试错后我想出了这个有效的解决方案。

使用with声明

with
u as (
  update my_table
    set some_value = $2
  where
    id = $1
  returning *
)
,
i as (
  insert into my_table (id, some_value)
    select $1, $2
  where 
    not exists(select * from u)
  returning *
)

select * from u
union
select * from i;

如果没有从更新返回的行,则首先尝试更新,然后返回更新的行,然后插入返回插入行的行。然后从更新和插入中选择返回值的并集,因为只有一个会发生,您将只返回一行。

希望这有帮助