我有一个功能:
echo *|fmt -w 1 |nl -s '.)' -w 1
通过比较create function fn_name_here() returns int as
$$
begin
with c as (
Select a1.accounts_id,sum(a2.quantity * a2.unit_price) as MRR
from account_subscriptions a1
inner join order_item a2 on a1.subscription_id = a2.account_subscriptions_id
group by a1.accounts_id
)
update summary s set MRR = c.MRR
from c
where c.accounts_id = s.accounts_id;
return 0;
end;
$$ language plpgsql
,我通过查询得到accounts_id
和mrr
并更新mrr
表中的summary
。
但如果accounts_id
表中还没有accounts_id
,我还需要在mrr
表格中插入一个新行,summary
和accounts_id
错误。
当我使用此查询编辑它并调用函数
时UPDATE dummy s SET mrr = c.MRR from c WHERE c.accounts_id = s.accounts_id ;
IF NOT FOUND THEN
INSERT INTO dummy (mrr,accounts_id)
select c.mrr,c.accounts_id from c;
END IF;
它正在抛出错误
relation "c" does not exist
LINE 1: ...TO dummy (mrr,accounts_id) select c.mrr,c.accounts_id from c
答案 0 :(得分:0)
表c
仅存在于UPDATE
语句的范围内,并且您无法在同一函数中的后续SQL语句中引用它。
不使用UPDATE
,您应该使用INSERT ... ON CONFLICT ... UPDATE
,这正是您所需要的。您只需要summary(accounts_id)
上的主键或唯一约束。
答案 1 :(得分:0)
注意:这是在9.4。
上测试的已在9.5或更高版本中引入了插入功能。
按照以下步骤检查插入或更新。您可以参考此内容并相应地更新您的功能。
第1步:
CREATE TABLE public.test
(
col1 text,
col2 text,
col3 integer
);
第2步:
insert into test values ('Old', 'Old', 1);
第3步:
drop function if exists test_insert_update();
create function test_insert_update() returns int as
$$
Declare findId boolean;
begin
/* Main Query starts from here as you have asked to create function that is why it is wrapped into it. This is sample example you can
modify it as per your requirement. */
with updateInsert as (
Select '' as col1,'updated' as col2, col3
from test abc
where col3 = 1
union
Select 'notUpdated' as col1, 'notUpdated' as col2, 2 as col3
), updateValues as (
-- this only updates your results
update test c1 set col3 = updateInsert.col3
, col2 = updateInsert.col2
from updateInsert
where updateInsert.col3 = c1.col3
RETURNING *
/*
I tried the example using with RETURNING * and without RETURNING * and both the time I recieved expected
result but in PostgreSQL documentation it is written in with clause.
As per documentation : 9.4
INSERT conforms to the SQL standard, except that the RETURNING clause is a PostgreSQL extension,
as is the ability to use WITH with INSERT. Also, the case in which a column name list is omitted,
but not all the columns are filled from the VALUES clause or query, is disallowed by the standard.
*/
)
Insert into test (col1, col2, col3)
select * from updateInsert where not exists(select * from test c1 where c1.col3 = updateInsert.col3);
/* Not exists clause is written to remove rows which has been updated. */
/* END */
return 0;
end;
$$
language 'plpgsql';
第5步:
select * from test_insert_update();
第6步:
select * from test;