PostgreSQL返回表函数调用结果列异常问题求助
PostgreSQL 返回表函数仅返回单列的问题分析与解决
先看你写的函数代码,逻辑是检查输入日期及后续1/2/3/5天是否为节假日,返回对应的标记:
CREATE OR REPLACE FUNCTION feiertag(inDate Date) RETURNS TABLE (eingabeDatum DATE, f_heute INT, f_1 INT, f_2 INT, f_3 INT, f_5 INT) AS $$ DECLARE f_heute integer := 0; f_1 integer := 0; f_2 integer := 0; f_3 integer := 0; f_5 integer := 0; BEGIN SELECT 1 INTO f_heute FROM feiertage where datum = inDate; SELECT 1 INTO f_1 FROM feiertage where datum = (inDate + interval '1' day); SELECT 1 INTO f_2 FROM feiertage where datum = (inDate + interval '2' day); SELECT 1 INTO f_3 FROM feiertage where datum = (inDate + interval '3' day); SELECT 1 INTO f_5 FROM feiertage where datum = (inDate + interval '5' day); RETURN QUERY SELECT inDate as eingabeDatum, coalesce(f_heute, 0) as f_heute, coalesce(f_1,0) as f_1, coalesce(f_2,0) as f_2, coalesce(f_3,0) as f_3, coalesce(f_5,0) as f_5 ; END; $$ LANGUAGE plpgsql;
你调用时得到的结果是这样的:
psql (9.5.12) Type "help" for help. tarec=> select feiertag('2017-01-01'); feiertag ------------------------ (2017-01-01,1,0,0,0,0) (1 row)
问题原因
这是PostgreSQL的默认行为:当你直接用SELECT 函数名(参数);调用返回TABLE类型的函数时,PostgreSQL会把整个表结果封装成一个复合类型返回,所以你看到的是一行一列,列值是所有字段的组合(用括号包裹的逗号分隔值)。
解决方法
有两种简单的方式可以得到你期望的多列结果:
方法1:用FROM子句调用函数(推荐)
把函数当作一个数据源来查询,这样PostgreSQL会自动展开表的各个列:
SELECT * FROM feiertag('2017-01-01');
执行后你会得到这样的结果:
eingabedatum | f_heute | f_1 | f_2 | f_3 | f_5 --------------+---------+-----+-----+-----+----- 2017-01-01 | 1 | 0 | 0 | 0 | 0 (1 row)
方法2:展开复合类型的字段
如果你一定要用SELECT直接调用函数,可以用括号包裹函数调用,然后加上.*来展开所有字段:
SELECT (feiertag('2017-01-01')).*;
这个方法也能得到相同的多列结果,但第一种方法更符合SQL的查询习惯,可读性更好。
额外提个小优化:你函数里用多次SELECT ... INTO的方式可以简化,比如用一次查询就把所有需要的标记查出来,不过这是次要的,核心问题已经通过调整调用方式解决啦~
内容的提问来源于stack exchange,提问作者Timo
相关产品推荐
相关产品推荐

