Postgres, обработка нескольких курсоров для результатов одного запроса - PullRequest
0 голосов
/ 21 января 2020

Как я могу использовать два курсора, один на основе выходных данных другого? в основном то, что я пытаюсь получить, это заменить все статусы, равные 'S', на предыдущие значения статуса.

  • Курсор day_to_process: перечисляет все даты, когда статус равен 'S'
  • Курсор status_to_process: получает последний статус перед 'S'

Ошибка, которую я получаю:

ОШИБКА: отсутствует запись предложения FROM для таблицы "day_to_process" Где: PL / pg SQL функция scrat.update_status ()

   create or replace function scrat.update_status() returns void
      language plpgsql
    as
    $$
    DECLARE
      day_to_process CURSOR FOR (SELECT distinct inst_status.status_date
                                 FROM scrat.inst_status
                                 WHERE inst_status.status = 'S'
                                 ORDER BY 1);

      status_to_process CURSOR for (select inst_status.status, max(inst_status.status_date)
                                    FROM scrat.inst_status
                                    where inst_status.status <> 'S'
                                      and inst_status.status_date < day_to_process.status_date
                                    group by status
                                    order by 2 desc
                                    limit 1);


      curr_date TEXT;
      curr_status TEXT;


    BEGIN
      OPEN day_to_process;
      OPEN status_to_process;

      LOOP
        FETCH day_to_process INTO curr_date;
        FETCH status_to_process INTO curr_status;

        update scrat.inst_status
        set inst_status.status = status_to_process.status
        where inst_status.status_date = curr_date;
      END LOOP;

    END ;
    $$;

Ответы [ 2 ]

1 голос
/ 21 января 2020

Вы не можете использовать имя курсора как таблицу.

Сначала вы должны FETCH строка результата в переменную record, затем вы можете использовать это.

Ваш второй объявление курсора не будет работать как объявление курсора stati c, потому что значение, извлеченное из первого курсора, изменится.

Вы должны попытаться обойтись без процедурного кода и записать все целиком в один UPDATE заявление.

0 голосов
/ 22 января 2020

Я выкладываю свое решение здесь, может, оно кому-нибудь поможет.

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

create function scrat.update_status() returns void
  language plpgsql
as
$$
DECLARE
  day_to_process CURSOR FOR (SELECT distinct inst_status.status_date
                             FROM scrat.inst_status
                             WHERE inst_status.status  ='S'
                             ORDER BY 1);

  curr_date date;
BEGIN

  OPEN day_to_process;
  <<day>>
  LOOP
    FETCH day_to_process INTO curr_date;
    exit day
    when not found;

    raise notice 'Processing Date %', curr_date::text;
   update scrat.inst_status
    set status  = (select a.status  from
                                  (select status , max(status_date)
                                FROM scrat.inst_status
                                where status  <> 'S'
                                  and status_date::date < curr_date
                                group by status 
                                order by 2 desc
                                limit 1)a)
    where inst_status.status_date = curr_date;

  END LOOP;
close day_to_process;
END ;
$$;
...