【问题标题】:Postgres , handling multiple cursors for one query resultsPostgres,为一个查询结果处理多个游标
【发布时间】:2020-01-21 13:02:13
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 我取下第二个游标并将查询放入更新中,然后我尝试将参数添加到第一个游标并将其作为记录,然后获取它,它工作了,但后来我return void 有问题(因为它是更新)它说不是 volatile 函数
    • 您应该为此打开一个新问题,并附上确切的错误消息。
    • 如果你想要并且你认为它可能对其他人有价值,那就去做吧。
    【解决方案2】:

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

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

    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 ;
    $$;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多