查询在函数 PostgreSQL 中没有结果数据的目的地

Query has no destination for result data in function PostgreSQL

我有一个函数 returns 对我产生了结果,但结果不是我所期望的并且捕获了我得到的错误消息:

query has no destination for result data

这是我的代码 postgresql:

CREATE OR REPLACE FUNCTION teltonika_funelement(
    raw character varying,
    tipo integer)
    RETURNS TABLE(id integer, nombre character varying, value1 character varying) 
    LANGUAGE 'plpgsql'

AS $BODY$
DECLARE     i     INT=1;
            y     INT=1;
            Len1  INT;
    ---------------------------------------------------------------------------
    
BEGIN

     CREATE TEMP TABLE Elements(ID Integer, Nombre CHARACTER VARYING, Value2 CHARACTER VARYING);

    
    IF Tipo=1 THEN
    
        Len1    := LENGTH(Raw)/4;

        WHILE i<=Len1
        LOOP
            INSERT INTO Elements
            SELECT
                 hex_to_int(SUBSTRING(Raw FROM y FOR 2))
                ,NULL
                ,SUBSTRING(Raw FROM y+2 FOR 2);

                 y  :=  y+4;

                 i  :=  i+1;
        END LOOP;
    END IF;
    ---------------------------------------------------------------------------
    ---------------------------------------------------------------------------
    IF Tipo = 2 THEN 
    
        Len1 := LENGTH(Raw)/6;
        
        WHILE i<=Len1
        LOOP
            INSERT INTO Elements
            SELECT
                 hex_to_int(SUBSTRING(Raw FROM y FOR 2))
                ,NULL
                ,SUBSTRING(Raw FROM y+2 FOR 4);

                y := y+6;

                i := i+1;
        END LOOP;
    END IF;
    ---------------------------------------------------------------------------
    ---------------------------------------------------------------------------
    IF Tipo = 4 THEN
    
        Len1 := LENGTH(Raw)/10;
        
        WHILE i<=Len1
        LOOP
            INSERT INTO Elements
            SELECT
                 hex_to_int(SUBSTRING(Raw FROM y FOR 2))
                ,NULL
                ,SUBSTRING(Raw FROM y+2 FOR 8);

                y := y+10;

                i := i+1;
        END LOOP;
    END IF;
    ---------------------------------------------------------------------------
    ---------------------------------------------------------------------------
    ---------------------------------------------------------------------------
    IF Tipo = 8 THEN
    
        Len1 := LENGTH(Raw)/18;
        
        WHILE i<=Len1
        LOOP
            INSERT INTO Elements
            SELECT
                 hex_to_int(SUBSTRING(Raw FROM y FOR 2))
                ,NULL
                ,SUBSTRING(Raw FROM y+2 FOR 16);

                y := y+18;

                i := i+1;
        END LOOP;
    END IF;
    ---------------------------------------------------------------------------

    SELECT
         E.ID
        ,PropertyName
        ,CASE
            WHEN (TypeParser = 'INT' AND Active=1) THEN (hex_to_int(Value2):: VARCHAR)
            WHEN (TypeParser = 'DECIMAL(18,1)/1000' AND Active=1)   THEN ((hex_to_int(Value2)/1000)::VARCHAR)
         ELSE 
            Value2
         END Value1
    FROM Elements E
    LEFT JOIN Teltonika_Tbl_ElementsConf TE ON TE.PropertyID=E.ID;
END;
$BODY$;

ALTER FUNCTION public.teltonika_funelement(character varying, integer)
    OWNER TO postgres;

这是错误信息:

query has no destination for result data 

我找不到错误的原因我试过像这样更改 return:

RETURNS TEXT AS 

请问如何解决,非常感谢您的帮助

非 void 函数需要 RETURN 对应于在 RETURNS 处声明的数据类型(或结构)。在你的例子中,一个 table 包含一个 integer 和两个 character varying。看看下面的测试函数,return 是一个 table 和一个 int 和一个 text 列:

CREATE OR REPLACE FUNCTION myfunc(int)
RETURNS TABLE(val int, txt text)  LANGUAGE 'plpgsql'
AS $$
BEGIN
  CREATE TEMPORARY TABLE tmp(id int,res text) ON COMMIT DROP;

  IF =0 THEN 
    INSERT INTO tmp VALUES (,'Invalid');
  ELSE 
    FOR i IN 1.. LOOP
     INSERT INTO tmp VALUES (i,'txt '||i);
    END LOOP;
  END IF;

  RETURN QUERY SELECT id,res FROM tmp;
END;
$$;

测试

SELECT * FROM myfunc(2);
 val |  txt  
-----+-------
   1 | txt 1
   2 | txt 2
(2 rows)

演示:db<>fiddle

一些想法:

  • 在 plpgsql 中,可以有多个 RETURN 语句,因此您的代码的不同部分 return 在不退出函数的情况下会有所不同。但是,如果您希望有一个中间 table 来收集信息并且 return 最后只收集一次,请确保 table 在函数完成后手动删除(或如果它引发错误!)或简单地将其创建为 ON COMMIT DROP。如果您更喜欢前者,请查看 .
  • 考虑使用 text 而不是 character varying
  • 您的 WHILE 循环使用增量值 1,直到达到某个限制。您可以使用 FOR 循环并删除 DECLARE 子句中的变量 i。这没什么大不了的,但根据您的功能大小,它可能会使事情变得更干净。
  • 您可以使用参数顺序代替其名称,例如。这也没什么大不了的,但它避免了冲突 and/or 与可能具有相同名称的列混淆。