почему результаты функции сохраняются с опозданием?

#database #postgresql #function #view

#База данных #postgresql #функция #Вид

Вопрос:

сегодня я столкнулся со странной проблемой. я хочу вызвать функцию plpgsql внутри представления (я знаю, что это плохой и странный способ вызова функции, поэтому, пожалуйста, не упоминайте об этом в своих ответах). я делаю это, но результаты функции применяются после показа результатов просмотра!!!

я хочу знать, как это возможно? и как я могу заставить функцию pgpgsql сохранить свой результат перед завершением запроса?

некоторая информация о моем коде:

план: это таблица о планах поездок, включая date_of_travel, цену и т.д.

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;
  

я хочу создать представление, содержащее два шага:

  1. вызов функции и план обновления.
  2. показать записи плана.

я попробовал приведенный ниже код

            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
  

я вижу, что изменения были применены.

как я могу увидеть изменения после первого запуска запроса без изменения метода?

если это непонятно, скажите мне, как указать точное определение функции, таблицы и представления

Комментарии:

1. Я думаю, нам понадобится код вашей функции, чтобы лучше понять, что вы пытаетесь сделать.

2. @ Arkena, я отредактировал свой вопрос. спасибо за комментарий

Ответ №1:

Результат не «сохраняется с опозданием», но Postgres скрывает изменения от вас, так что запросы ведут себя предсказуемо.

Управление параллелизмом Postgres означает, что запрос не увидит никаких изменений после его запуска. Это верно, даже если ваш собственный запрос вносит изменения, и нет способа избежать этого.

Вместо этого вы могли бы создать функцию, возвращающую набор, которая сначала выполняет удаление, а затем возвращает содержимое таблицы с помощью второго запроса. Затем создайте представление, которое выбирает из этой функции.

 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();
  

Комментарии:

1. большое вам спасибо, это точная причина проблемы и хорошее решение для нее, все работает нормально.