我来自SQL Server到PostgreSQL(9.0),所以我在执行它时在存储过程/函数中遇到问题。该函数返回此错误消息:
SQLSTATE:42601;
SQLERRM:查询没有结果数据的目的地
我需要做什么将SELECT
查询选择的列中的值与OUT
参数一起传递到结果中,并避免收到该错误消息?
CREATE OR REPLACE FUNCTION myplfunction(
IN i_param1 character varying,
IN i_param2 character varying,
IN i_param3 character varying,
IN i_param4 character varying,
OUT o_call_status integer,
OUT o_call_message character varying)
RETURNS record AS
$BODY$
DECLARE
val1 varchar;
val2 varchar;
...
IF (v_solution_id IS NULL) THEN
val1 := column1 FROM tbl2 WHERE column2= i_param1;
IF(val1 IS NULL) THEN
o_call_status := 1005;
o_call_message := column1 is not configured or invalid';
RETURN;
END IF;
SELECT 'mycolumnname1' as paramName,mycolumn1 as value FROM tb1 WHERE column1 = val
UNION ALL
SELECT 'mycolumnname2' as paramName,,mycolumn2 as value FROM tb1 WHERE column1 = val
UNION ALL
SELECT 'mycolumnname2' as paramName,,mycolumn2 as value FROM tb2 WHERE column2 = val2
WHERE tb2paramName4=i_val3;
o_call_status := 0;
o_call_message := '';
EXCEPTION WHEN OTHERS THEN
o_call_message := SQLERRM;
o_call_status := SQLSTATE;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
答案 0 :(得分:1)
通常,PostgreSQL函数只返回单个值(或行)或一组值(或行),但不能并行返回。
您可以直接从函数返回一组或多行,使其成为“设置返回函数”,a.k.a。“表函数”。那么除了每行返回参数o_call_status
和o_call_message
之外你别无选择(如果你实际上根本需要它们的话?)
CREATE OR REPLACE FUNCTION myplfunction(i_val1 int, i_val2 int)
RETURNS TABLE (col1 text, col2 text -- use matching types!
, o_call_status text -- text, not int
, o_call_message text) AS
$func$
BEGIN
RETURN QUERY
SELECT col1, col2
, '0'::text AS o_call_status
, ''::text AS o_call_message -- column aliases irrelevant here
FROM tb1
WHERE col3 = i_val1
UNION ALL
SELECT col4, col5, '0'::text, ''::text
FROM tb2
WHERE col6 = i_val2
AND col7 = i_val3; -- WHERE was specified twice
EXCEPTION WHEN OTHERS THEN
RETURN QUERY
SELECT NULL::text, NULL::text, SQLERRM, SQLSTATE;
END
$func$ LANGUAGE plpgsql;
特殊变量SQLERRM
的类型为text
,顺便说一句。不是integer
。
或者您必须打开游标以将返回的表与这两个参数分离。
CREATE OR REPLACE FUNCTION myplfunction(
i_val1 text, i_val2 text, i_val3 text, i_val4 text
, OUT o_call_status text
, OUT o_call_message text) AS
$func$
DECLARE
curs CURSOR FOR
SELECT col1, col2 FROM tb1
WHERE col3 = i_val1
UNION ALL
SELECT col4, col5 FROM tb2
WHERE col6 = i_val2
AND col7 = i_val3;
BEGIN
OPEN curs;
o_call_status := '0';
o_call_message := '';
EXCEPTION WHEN OTHERS THEN
o_call_status := SQLSTATE;
o_call_message := SQLERRM;
END
$func$ LANGUAGE plpgsql;
但是,游标只存在于同一个事务中。因此,您需要在COMMIT
或ROLLBACK
之前获取值。
BEGIN;
SELECT * FROM myplfunction (10, 20, 30, 40);
FETCH ALL IN curs;
ROLLBACK;
您甚至可以提交任意光标名称。 This and other details in the manual.
还有more information about errors available since Postgres 9.3.。