Почему я получаю эту ошибку при выполнении функции Postgres - PullRequest
0 голосов
/ 25 февраля 2019
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.
CONTEXT: PL / pgSQL function flowrate7 ()строка 19 в операторе SQL Состояние SQL: 42601

1 Ответ

0 голосов
/ 25 февраля 2019

Вы неверно получаете значения в переменные.Чтобы сохранить значение результата запроса в переменной (или двух), вам нужно использовать 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
  • , получить одну строку из 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;  
...