0

我如何使用两个光标,一个基于另一个的输出?基本上我想要得到的是用以前的状态值替换所有等于“S”的状态。

  • 光标 day_to_process:列出状态等于“S”的所有日期
  • 光标 status_to_process :正在获取“S”之前的最后一个状态

我得到的错误是:

错误:缺少表“day_to_process”的 FROM 子句条目其中:PL/pgSQL 函数 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 ;
    $$;
4

2 回答 2

1

不能像表格那样使用游标名称。

您首先必须将FETCH结果行放入record变量中,然后您可以使用它。

您的第二个游标声明不能用作静态游标声明,因为从第一个游标中获取的值发生了变化。

您应该尝试不使用过程代码并将整个事情写在一个UPDATE语句中。

于 2020-01-21T13:25:23.843 回答
0

我在这里发布我的解决方案,也许它会对某人有所帮助。

因为我们不能使用像表名这样的游标,所以我取下了第二个游标,只需将查询放在更新中

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 ;
$$;
于 2020-01-22T11:05:15.843 回答