Postgres,为一个查询结果处理多个游标

时间:2020-01-21 13:02:13

标签: postgresql function stored-procedures cursor multiple-cursor

我如何使用两个光标,一个基于另一个的输出? 基本上我想要得到的是用以前的状态值替换所有等于“ 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 ;
    $$;

2 个答案:

答案 0 :(得分:1)

您不能使用像表这样的游标名称。

您首先必须将结果行record放入UPDATE变量中,然后才能使用它。

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

您应该尝试不使用过程代码,而将整个内容写在单个 this.setState( prevState => ({ saved: [...prevState.saved, headline] }, () => { console.log('Saved articles = ', this.state.saved), alert('Article saved'), localStorage.setItem('saved', JSON.stringify(this.state.saved)), localStorage.getItem('saved') })); 语句中。

答案 1 :(得分: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 ;
$$;
相关问题