SQL 函数返回类型:TABLE vs SETOF 记录

Posted

技术标签:

【中文标题】SQL 函数返回类型:TABLE vs SETOF 记录【英文标题】:SQL function return-type: TABLE vs SETOF records 【发布时间】:2014-04-20 20:43:14 【问题描述】:

返回TABLESETOF records 的函数有什么区别,其他条件相同。

CREATE FUNCTION events_by_type_1(text) RETURNS TABLE(id bigint, name text) AS $$
    SELECT id, name FROM events WHERE type = $1;
$$ LANGUAGE SQL STABLE;

CREATE FUNCTION events_by_type_2(text) RETURNS SETOF record AS $$
    SELECT id, name FROM events WHERE type = $1;
$$ LANGUAGE SQL STABLE;

这些函数似乎返回相同的结果。看到这个SQLFiddle。

【问题讨论】:

【参考方案1】:

当返回SETOF record 时,输出列没有类型,也没有命名。因此,这种形式不能直接用在 FROM 子句中,就好像它是子查询或表一样。

即发行时:

SELECT * from events_by_type_2('social');

我们得到这个错误:

错误:返回的函数需要列定义列表 “记录”

它可以被 SQL 调用者“转换”为正确的列类型。这种形式确实有效:

SELECT * from events_by_type_2('social') as (id bigint, name text);

结果:

编号 |姓名 ----+---------------- 1 |舞会 2 |欢乐时光 ...

因此SETOF record 被认为不太实用。只有在事先不知道结果的列类型时才应该使用它。

【讨论】:

@MattDiPasquale:我不知道任何性能差异。但是,在这两种情况下,如果在更复杂的查询中使用这些函数,您可能会对 How to avoid multiple function evals with the (func()).* syntax in an SQL query? 感兴趣【参考方案2】:

这个答案只是为了记住 TABLESETOF 等效的替代上下文

正如@a_horse_with_no_name 所指出的,它不是RETURNS SETOF“未知记录”,而是已定义的记录。


在本例中,tablesetof 类型是等价的,

CREATE TYPE footype AS (score int, term text);

CREATE FUNCTION foo() RETURNS SETOF footype AS $$
   SELECT * FROM ( VALUES (1,'hello!'), (2,'Bye') ) t;
$$ language SQL immutable;

CREATE FUNCTION foo_tab() RETURNS TABLE (score int, term text) AS $$
   SELECT * FROM ( VALUES (1,'hello!'), (2,'Bye') ) t;
$$ language SQL immutable;

SELECT * FROM foo();      -- works fine!
SELECT * FROM foo_tab();  -- works fine and is equivalent.

RETURNS SETOF 具有重用类型的优点(参见 footype),这是 RETURNS TABLE不可能做到的>。

【讨论】:

returns setof footypeRETURNS SETOF record 不同,因为现在它不再是“未知”类型。 footype 的列定义明确。 谢谢你,@PeterKrauss。 :-)

以上是关于SQL 函数返回类型:TABLE vs SETOF 记录的主要内容,如果未能解决你的问题,请参考以下文章

在 WHILE LOOP 部分之后从 PostgreSQL 函数返回 SETOF 行

从另一个查询调用时,返回 SETOF 记录会丢失记录类型

怎样用sql server自定义函数,实现动态的sql,返回一个table类型

从函数返回时复合数据类型缺失值

SQL EXISTS vs. Aggregate IS NOT NULL

Snowflake 中的返回类型“Table”问题