почему результаты функции сохраняются поздно? - PullRequest
0 голосов
/ 04 апреля 2019

сегодня я столкнулся со странной проблемой. я хочу вызвать функцию 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 голосов
/ 04 апреля 2019

Результат не "сохраняется поздно", но 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...