如何 return 一个 table 的行类型加上一个函数的附加列?
How to return a table's rowtype plus an additional column from a function?
我有一个 table 定义如下:
create table users (
id serial primary key,
name text,
email text,
);
...我想编写一个函数,其中 returns 行的形状为:
(
id integer,
name text,
email text,
some_other_column boolean,
)
我设法使用下面的代码实现了这一点,但我不想重新定义用户的列 table:
create or replace function get_users ()
returns table (
id integer,
name text,
email text,
some_other_column boolean,
) as $$
select users.*, true as some_other_column from users;
$$ language sql;
有没有办法通过执行类似的操作来动态创建行类型? (postgres 抱怨 users.*
处的语法错误):
create or replace function get_users ()
returns table (
users.*,
some_other_column boolean
) as $$
select users.*, true as some_other_column from users;
$$ language sql;
请注意,直接执行以下查询就可以正常工作:
select users.*, true as some_other_column from users;
这里的最终目标是最终得到一个像 select * from get_users()
这样的可调用函数,其中 returns 行包括现有 table 中的列和其他列。我不希望调用者担心究竟如何调用该函数。
我的假设是,由于我可以编写简单的 sql returns 动态行,所以我应该能够以某种方式将 sql 存储在数据库中,从而保留返回行的结构。
您可以将 table 视为伪类型,但您必须对函数和调用此函数的查询进行一些更改,如下所示。
正在创建:
create or replace function get_users ()
returns table (
row_users users,
some_other_column boolean
) as $$
select t, true as some_other_column from users as t;
$$ language sql;
通话中:
SELECT (row_users).*, some_other_column FROM get_users();
事实上,您可以尝试另一种 return 类型的动态结构,例如 Refcursor or JSON ...这取决于您使用的语言或应用程序。
否。 目前没有办法做到这一点(包括第 10 页)。
SQL 是一种严格类型的语言。创建函数时,必须声明 return 类型。要 return 一组 行 (您可以用 SELECT * FROM srf()
调用):
您可以 return 匿名记录 (RETURNS SETOF record
)。但是你必须在每次调用时提供一个列定义列表。
您可以 return 多态(行)类型 (RETURNS SETOF anyelement
)。但是您必须提供行类型 (composite type) 作为函数的参数,并且行类型需要以某种方式在系统中注册 .
- Refactor a PL/pgSQL function to return the output of various SELECT queries
您可以明确使用任何已注册的行类型,RETURNS SETOF
rowtype
。副作用是函数现在取决于行类型。
您可以使用 RETURNS TABLE (...)
临时定义 returned 行类型 - 您甚至可以混合行类型(composite types) and simple types. But a simple SELECT * FROM srf()
will not decompose nested row types - like Mabu's answer 去演示。
相关:
- Return SETOF rows from PostgreSQL function
归结为:
Is there a way to dynamically create a row type by doing something like this?
不,没有。 SELECT * FROM ...
将从系统目录中检索列定义列表,其中行类型必须在 之前注册 您可以这样调用该函数。
通常最好在 RETURNS TABLE ()
子句中拼出列定义列表。这避免了依赖性。如果您需要根据现有 table 快速注册行类型而不拼写其列,您可以创建 VIEW
- 或者 TEMPORARY VIEW
如果它仅用于当前会话:
CREATE TEMP VIEW v_users_plus AS
SELECT *, NULL::boolean AS some_other_column FROM users;
这会在系统中注册同名 (v_users_plus
) 的行类型,就像任何其他 table 或视图一样。对于非临时函数,显然需要非临时行类型。
我有一个 table 定义如下:
create table users (
id serial primary key,
name text,
email text,
);
...我想编写一个函数,其中 returns 行的形状为:
(
id integer,
name text,
email text,
some_other_column boolean,
)
我设法使用下面的代码实现了这一点,但我不想重新定义用户的列 table:
create or replace function get_users ()
returns table (
id integer,
name text,
email text,
some_other_column boolean,
) as $$
select users.*, true as some_other_column from users;
$$ language sql;
有没有办法通过执行类似的操作来动态创建行类型? (postgres 抱怨 users.*
处的语法错误):
create or replace function get_users ()
returns table (
users.*,
some_other_column boolean
) as $$
select users.*, true as some_other_column from users;
$$ language sql;
请注意,直接执行以下查询就可以正常工作:
select users.*, true as some_other_column from users;
这里的最终目标是最终得到一个像 select * from get_users()
这样的可调用函数,其中 returns 行包括现有 table 中的列和其他列。我不希望调用者担心究竟如何调用该函数。
我的假设是,由于我可以编写简单的 sql returns 动态行,所以我应该能够以某种方式将 sql 存储在数据库中,从而保留返回行的结构。
您可以将 table 视为伪类型,但您必须对函数和调用此函数的查询进行一些更改,如下所示。
正在创建:
create or replace function get_users ()
returns table (
row_users users,
some_other_column boolean
) as $$
select t, true as some_other_column from users as t;
$$ language sql;
通话中:
SELECT (row_users).*, some_other_column FROM get_users();
事实上,您可以尝试另一种 return 类型的动态结构,例如 Refcursor or JSON ...这取决于您使用的语言或应用程序。
否。 目前没有办法做到这一点(包括第 10 页)。
SQL 是一种严格类型的语言。创建函数时,必须声明 return 类型。要 return 一组 行 (您可以用 SELECT * FROM srf()
调用):
您可以 return 匿名记录 (
RETURNS SETOF record
)。但是你必须在每次调用时提供一个列定义列表。您可以 return 多态(行)类型 (
RETURNS SETOF anyelement
)。但是您必须提供行类型 (composite type) 作为函数的参数,并且行类型需要以某种方式在系统中注册 .- Refactor a PL/pgSQL function to return the output of various SELECT queries
您可以明确使用任何已注册的行类型,
RETURNS SETOF
rowtype
。副作用是函数现在取决于行类型。您可以使用
RETURNS TABLE (...)
临时定义 returned 行类型 - 您甚至可以混合行类型(composite types) and simple types. But a simpleSELECT * FROM srf()
will not decompose nested row types - like Mabu's answer 去演示。
相关:
- Return SETOF rows from PostgreSQL function
归结为:
Is there a way to dynamically create a row type by doing something like this?
不,没有。 SELECT * FROM ...
将从系统目录中检索列定义列表,其中行类型必须在 之前注册 您可以这样调用该函数。
通常最好在 RETURNS TABLE ()
子句中拼出列定义列表。这避免了依赖性。如果您需要根据现有 table 快速注册行类型而不拼写其列,您可以创建 VIEW
- 或者 TEMPORARY VIEW
如果它仅用于当前会话:
CREATE TEMP VIEW v_users_plus AS
SELECT *, NULL::boolean AS some_other_column FROM users;
这会在系统中注册同名 (v_users_plus
) 的行类型,就像任何其他 table 或视图一样。对于非临时函数,显然需要非临时行类型。