我需要一个使用标识符的函数来选择dos表,并返回具有这些表中过程值的另一个表。
让我们考虑以下表格:
表 sum1_suffix
id | digit1
----+--------
1 | 2
2 | 8
3 | 7
4 | 5
表 sum2_suffix
id | digit2
----+--------
1 | 7
2 | 3
3 | 9
4 | 1
我的功能:
CREATE OR REPLACE FUNCTION public.add(IN tablesuffix character varying)
RETURNS TABLE(result integer) AS
$BODY$
DECLARE
var_r record;
tabla_s1 character varying;
tabla_s2 character varying;
cadena_sql TEXT; --for debugging
BEGIN
tabla_s1 := quote_ident(CONCAT('sum1_',tablesuffix));
tabla_s2 := quote_ident(CONCAT('sum2_',tablesuffix));
EXECUTE
--cadena_sql :=
'FOR var_r IN( SELECT ' ||
tabla_s1 ||'.digit1 , '||tabla_s2 ||'.digit2
FROM '||tabla_s1||','||tabla_s2||
' WHERE '||tabla_s1||'.id ='|| tabla_s2||'.id)
LOOP
result := var_r.digit1 + var_r.digit2
RETURN NEXT;
END LOOP;';
RAISE NOTICE 'cadena sql es %',cadena_sql;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION public.add(character varying)
OWNER TO postgres;
最后,我调用该函数:
select * from add('suffix');
但是我得到这个错误:
ERROR: syntax error at or near "FOR"
LINE 1: FOR var_r IN( SELECT sum1_code.digit1 , sum2_code.digit2
^
我也尝试修改此行:
'FOR var_r IN(SELECT ' ||
以这种方式:
'FOR '||var_r ||' IN(SELECT ' ||
但随后出现下一个错误:
ERROR: record "var_r" is not assigned yet
DETAIL: The tuple structure of a not-yet-assigned record is indeterminate.
CONTEXT: SQL statement "SELECT 'FOR '||var_r ||' IN(SELECT ' ||
...........
(注意,我没有用过FORMAT()来执行,因为在实际查询中,我大约有20个 I%参数,对我来说更具可读性,不要使用这种方式,至少直到我已经解决了主要问题。)
答案 0 :(得分:1)
我注意到该函数存在几个错误:
第一
您不能将控件结构与EXECUTE
EXECUTE
--cadena_sql :=
'FOR var_r IN( SELECT ' ||
tabla_s1 ||'.digit1 , '||tabla_s2 ||'.digit2
FROM '||tabla_s1||','||tabla_s2||
' WHERE '||tabla_s1||'.id ='|| tabla_s2||'.id)
LOOP
result := var_r.digit1 + var_r.digit2
RETURN NEXT;
END LOOP;';
第二
没有+
运算符来改变字符类型。
result := var_r.digit1 + var_r.digit2
考虑到这些要点,也许这可以解决
CREATE OR REPLACE FUNCTION public.add(IN tablesuffix character varying)
RETURNS TABLE(result integer) AS
$BODY$
DECLARE
var_r record;
tabla_s1 character varying;
tabla_s2 character varying;
cadena_sql TEXT; --for debugging
BEGIN
tabla_s1 := quote_ident(CONCAT('sum1_',tablesuffix));
tabla_s2 := quote_ident(CONCAT('sum2_',tablesuffix));
--cadena_sql :=
FOR var_r IN EXECUTE 'SELECT ' ||
tabla_s1 ||'.digit1 , '||tabla_s2 ||'.digit2
FROM '||tabla_s1||','||tabla_s2||
' WHERE '||tabla_s1||'.id ='|| tabla_s2||'.id'
LOOP
result := var_r.digit1::int + var_r.digit2::int;
RETURN NEXT;
END LOOP;
RAISE NOTICE 'cadena sql es %',cadena_sql;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION public.add(character varying)
OWNER TO postgres;