今天我遇到了一个奇怪的问题。我想在 View 中调用 plpgsql 函数(我知道调用函数是一种糟糕且奇怪的方式,所以请不要在您的回答中提及它)。我这样做了,但是函数的结果在显示 View 的结果之后应用!!!
我想知道这怎么可能?以及如何在完成查询之前强制 pgpgsql 函数存储其结果?
关于我的代码的一些信息:
计划:这是一张关于旅行计划的表格,包括旅行日期、价格等。
travel_check(): 这是一个函数,从计划表中删除那些 date_of_travel 小于 current_date 的记录,并将它们存储到另一个表并返回一个整数。(这并不重要,所以记住这个函数会删除一些记录来自计划表),但我在下面写下了确切的定义:
create or replace function finish_travel(todelete integer) returns void as
$body$
begin
create table if not exists history_of_travel(
id integer,
traveldate date,
source_id char(3),
destination_id char(3),
timeofday time
);
insert into history_of_travel
select id,traveldate,source_id,destination_id,timeofday
from plan
where id=todelete;
delete from plan where id=todelete;
end;
$body$
language plpgsql volatile;
create or replace function travel_check() returns int as
$body$
declare
trip record;
begin
for trip in select *
from plan
loop
if(trip.traveldate<current_date) then
perform finish_travel(trip.id);
end if;
if(trip.traveldate=current_date and trip.timeofday=now()::timestamp(0)::time) then
perform finish_travel(trip.id);
end if;
end loop;
return 1;
end;
$body$
language plpgsql volatile;
我想创建一个包含两个步骤的 View :
- 调用函数和更新计划。
- 展示计划的记录。
我试过下面的代码
create view clients_select_query as
select plan.*
from plan,(select travel_check()) as d
where exists(select * from plan)
当我运行时:
select * from clients_select_query
不幸的是它显示了计划表的内容没有任何变化
但如果我再次运行:
select * from clients_select_query
或
select * from plan
我看到更改已应用。
如何在不更改方法的情况下首次运行查询后看到更改?
如果不清楚,告诉我函数、表和 View 的确切定义
最佳答案
结果不是“延迟保存”,而是 Postgres 对您隐藏了更改,因此查询的行为是可预测的。
Postgres 的 concurrency control意味着查询在开始运行后不会看到任何更改。即使您自己的查询正在进行更改也是如此,并且没有办法避免它。
相反,您可以创建一个返回集合的函数,它首先执行删除操作,然后使用第二个查询返回表的内容。然后,创建一个从该函数中选择的 View 。
create function clients_select_function() returns setof plan as $$
select travel_check();
select * from plan;
$$
language sql;
create view clients_select_query as
select * from clients_select_function();
关于database - 为什么函数结果保存较晚?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55511246/