我有一个函数可以将结果返回给我,但结果不是我所期望的,并且捕获了我收到的错误消息:
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
我找不到错误的原因我尝试像这样更改返回:
RETURNS TEXT AS
我该如何解决,非常感谢您的帮助
答案 0 :(得分:0)
非 void 函数需要 RETURN
对应于在 RETURNS
处声明的数据类型(或结构)。在您的情况下,包含一个 integer
和两个 character varying
的表。考虑以下测试函数,它返回一个包含 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 $1=0 THEN
INSERT INTO tmp VALUES ($1,'Invalid');
ELSE
FOR i IN 1..$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
一些想法:
RETURN
语句,以便代码的不同部分在不退出函数的情况下返回不同的内容。但是,如果您更喜欢有一个中间表来收集信息并最终只返回一次,请确保在函数完成后手动删除该表(或者如果它引发错误!)或者只是将其创建为ON COMMIT DROP
。如果您更喜欢前者,请考虑UNLOGGED TABLES
。text
而不是 character varying
。WHILE
循环使用增量值 1,直到达到某个限制。您可以使用 FOR
循环并去掉 i
子句中的变量 DECLARE
。这没什么大不了的,但根据您的函数大小,它可能会让事情变得更简洁。$1
。这也没什么大不了的,但它可以避免与可能具有相同名称的列发生冲突和/或混淆。