是否可以为某些PostgreSQL函数定义任意返回类型?
这个想法是,根据呼叫,输出可能会以不同的方式返回。
例如,假设我们有:
TypeA : (name, email)
TypeB : (name, email, address, phone)
我们可能有一个功能:
func1(name varchar);
但返回类型可以是:TypeA
或TypeB
那么,是否可以定义func1,以便任意返回类型有效?
修改
如果解决方案是 refcursor ...有人可以根据我的问题中的示例写一个答案吗?这会有很大的帮助!
答案 0 :(得分:3)
您有几个选择。第一种是使用将在调用时强制转换的多态类型,第二种是使用强制转换,第三种是返回refcursor。
多态类型
在这种情况下,您可以执行以下操作:
CREATE FUNCTION foo (bar varchar, baz ANYELEMENT) returns ANYELEMENT AS
$$
SELECT 'test'::TEXT;
$$ language sql;
然后调用它,你会在调用时转换NULL参数:
SELECT * FROM foo('test', null::varchar);
你遇到的真正问题是你必须在每次通话时指定一个类型。
带投射的单一返回类型
在您的示例中,一种类型具有另一种类型的字段子集。所以你可以:
CREATE TYPE all_info AS (
name text,
email text,
address text,
phone text
);
CREATE TYPE email_only AS (
name text,
email text
);
CREATE FUNCTION email_only(all_info) returns email_only LANGUAGE SQL IMMUTABLE AS $$
SELECT $1.name, $1.email;
$$;
CREATE CAST (all_info as email_only) WITH FUNCTION email_only(all_info);
然后你创建你的函数来返回all_info,你可以在输出上进行转换。类似的东西:
SELECT (f::email_only).* FROM my_function('foo') f;
请注意,这两个允许您使用SQL语言函数,而reframeors则不会这样做。
<强> REFCURSOR 强>
在这种情况下,您必须使用plpgsql
CREATE OR REPLACE FUNCTION foo(bar varchar) RETURNS refcursor LANGUAGE plpgsql AS
$$
DECLARE a REFCURSOR;
BEGIN
OPEN a FOR SELECT ....;
RETURN a;
END;
$$;
总的来说,我认为从超集和演员方法开始比其他方式更容易。反射器可能是第二种方法。最后一个是坚持一个类型的演员。