为什么我在执行Postgres函数时遇到此错误

时间:2019-02-25 07:21:40

标签: postgresql plpgsql

CREATE OR REPLACE FUNCTION public.flowrate7(
    )
    RETURNS TABLE(oms_id integer, flowrate numeric, chakno character varying) 
    LANGUAGE 'plpgsql'

    COST 100
    VOLATILE 
    ROWS 1000
AS $BODY$

    declare temp_omsId integer;
    declare temp_flowrate numeric(20,3);
    declare temp_chakno varchar(100);

begin

DROP TABLE IF EXISTS tbl_oms;
DROP TABLE IF EXISTS tbl_calFlow;

        CREATE temporary TABLE tbl_oms(omsid__ integer) ON COMMIT DELETE ROWS;
        CREATE temporary TABLE tbl_calFlow(OmsId_ integer,FlowRate_ numeric(20,3),ChakNo_ varchar(100)) ON COMMIT DELETE ROWS;

            insert into tbl_oms (select OmsId from MstOms);

            while (select count(*) from tbl_oms) <> 0 LOOP

            select temp_omsId = omsid__ from tbl_oms LIMIT 1;


        temp_flowrate = (select (case when(InLetPressure > 0.5) then 1 else 0 end) from MstOms where OmsId = temp_omsId);
        temp_chakno = (select ChakNo  from MstOms where OmsId = temp_omsId);

                insert into tbl_calFlow values (temp_omsId,temp_flowrate,temp_chakno);

                delete from tbl_oms where omsid__ = temp_omsId; 

            END LOOP;

            return query (select OmsId_,FlowRate_,ChakNo_ from tbl_calFlow);
end;
$BODY$;
  

错误:查询没有结果数据的目的地
  提示:如果要舍弃SELECT的结果,请改用PERFORM。
  上下文:SQL语句中的PL / pgSQL函数flowrate7()第19行   SQL状态:42601

1 个答案:

答案 0 :(得分:0)

您将值错误地检索到变量中。要将查询结果的值存储到一个(或两个)变量中,您需要使用select .. into variable ...

CREATE OR REPLACE FUNCTION public.flowrate7()
    RETURNS TABLE(oms_id integer, flowrate numeric, chakno character varying) 
    LANGUAGE plpgsql 
AS $BODY$

declare 
  temp_omsId integer;
  temp_flowrate numeric(20,3);
  temp_chakno varchar(100);
begin

  DROP TABLE IF EXISTS tbl_oms;
  DROP TABLE IF EXISTS tbl_calFlow;

  CREATE temporary TABLE tbl_oms(omsid__ integer) ON COMMIT DELETE ROWS;
  CREATE temporary TABLE tbl_calFlow(OmsId_ integer,FlowRate_ numeric(20,3),ChakNo_ varchar(100)) ON COMMIT DELETE ROWS;

  insert into tbl_oms 
  select OmsId 
  from MstOms;

  while (select count(*) from tbl_oms) <> 0 LOOP

    select omsid__  
       into temp_omsId   --<< here
    from tbl_oms LIMIT 1;

    select case when inletpressure> 0.5 then 1 else 0 end, chakno 
      into temp_flowrate, temp_chakno --<< here
    from MstOms 
    where omsid = temp_omsId;

    insert into tbl_calFlow values (temp_omsId,temp_flowrate,temp_chakno);
    delete from tbl_oms where omsid__ = temp_omsId; 

  END LOOP;

  return query select omsid_, flowrate_, chakno_ 
               from tbl_calflow;
end;
$BODY$;

但是该函数的处理不必要地复杂

  • 如果首先将所有行MstOms复制到tmp_MstOms
  • 从tbl_oms中检索一行的ID
  • 从MstOms中检索一行以计算流量
  • 将该行存储在临时表中
  • 从(其他)临时表中删除刚刚处理的行
  • 计算tbl_oms中的行数或行数,如果不为零,则移至“下一个”行

这是一种计算简单值的效率极低且复杂的方法,不适用于大型表。

首先对数据库中的表进行逐行处理是一种反模式(通过删除,插入和计算行数,这样做会变得更慢)。

这不是用SQL完成事情的方式。整个无效循环可以用单个查询替换,这也使您可以将整个内容更改为SQL函数。

CREATE OR REPLACE FUNCTION public.flowrate7()
    RETURNS TABLE(oms_id integer, flowrate numeric, chakno character varying) 
    LANGUAGE sql
AS $BODY$
  select omsid, 
         case when inletpressure> 0.5 then 1 else 0 end as flowrate, 
         chakno 
  from mstoms;    
$BODY$;

实际上,一种观点对此更为合适。

create or replace view flowrate7
as
select omsid, 
       case when inletpressure> 0.5 then 1 else 0 end as flowrate, 
       chakno 
from mstoms;