是否可以让PostgreSQL函数返回“;任意”;类型?

是否可以让PostgreSQL函数返回“;任意”;类型?,sql,database,postgresql,Sql,Database,Postgresql,是否可以为某些PostgreSQL函数定义任意返回类型 其思想是,根据调用的不同,可能会以不同的方式返回输出 例如,假设我们有: TypeA : (name, email) TypeB : (name, email, address, phone) 我们可能有一个功能: func1(name varchar); 但是返回类型可以是:TypeA或TypeB 那么,是否可以定义func1以使任意返回类型工作 编辑: 如果解决方案是refcursor。。。有人能根据我问题中的例子写一个答案吗?那会

是否可以为某些PostgreSQL函数定义任意返回类型

其思想是,根据调用的不同,可能会以不同的方式返回输出

例如,假设我们有:

TypeA : (name, email)
TypeB : (name, email, address, phone)
我们可能有一个功能:

func1(name varchar);
但是返回类型可以是:
TypeA
TypeB

那么,是否可以定义func1以使任意返回类型工作

编辑:


如果解决方案是refcursor。。。有人能根据我问题中的例子写一个答案吗?那会很有帮助的

您有几个选择。第一种是使用多态类型,该类型将在调用时强制转换,第二种是使用强制转换,第三种是返回refcursor

多态类型

在这种情况下,您可以执行以下操作:

 CREATE FUNCTION foo (bar varchar, baz ANYELEMENT) returns ANYELEMENT AS
 $$
   SELECT 'test'::TEXT;
 $$ language sql;
SELECT (f::email_only).* FROM my_function('foo') f;
然后要调用它,您将在调用时强制转换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);
然后创建函数以返回所有_信息,并可以对输出进行强制转换。比如:

 CREATE FUNCTION foo (bar varchar, baz ANYELEMENT) returns ANYELEMENT AS
 $$
   SELECT 'test'::TEXT;
 $$ language sql;
SELECT (f::email_only).* FROM my_function('foo') f;
请注意,这两个函数允许您使用引用游标不支持的SQL语言函数

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;
$$;

总的来说,我认为从超集和演员阵容开始比其他方法更容易。Refcursors可能是第二种方法。最后一个是坚持对某一类型进行强制转换。

您有几个选择。第一种是使用多态类型,该类型将在调用时强制转换,第二种是使用强制转换,第三种是返回refcursor

多态类型

在这种情况下,您可以执行以下操作:

 CREATE FUNCTION foo (bar varchar, baz ANYELEMENT) returns ANYELEMENT AS
 $$
   SELECT 'test'::TEXT;
 $$ language sql;
SELECT (f::email_only).* FROM my_function('foo') f;
然后要调用它,您将在调用时强制转换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);
然后创建函数以返回所有_信息,并可以对输出进行强制转换。比如:

 CREATE FUNCTION foo (bar varchar, baz ANYELEMENT) returns ANYELEMENT AS
 $$
   SELECT 'test'::TEXT;
 $$ language sql;
SELECT (f::email_only).* FROM my_function('foo') f;
请注意,这两个函数允许您使用引用游标不支持的SQL语言函数

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;
$$;

总的来说,我认为从超集和演员阵容开始比其他方法更容易。Refcursors可能是第二种方法。最后一个是坚持要为某一类型演员阵容。

Glenn,谢谢,但你能举个小例子吗。这将大有帮助。下面有一些例子。可能不是你想要的,但这是一种可能的技术。格伦,谢谢,但你能举个小例子吗。这将大有帮助。下面有一些例子。可能不是你想要的,但这是一种可能的技术。