SQL 函数返回类型:TABLE vs SETOF 记录
Posted
技术标签:
【中文标题】SQL 函数返回类型:TABLE vs SETOF 记录【英文标题】:SQL function return-type: TABLE vs SETOF records 【发布时间】:2014-04-20 20:43:14 【问题描述】:返回TABLE
与SETOF 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】:这个答案只是为了记住 TABLE 和 SETOF 等效的替代上下文。
正如@a_horse_with_no_name 所指出的,它不是RETURNS SETOF“未知记录”,而是已定义的记录。
在本例中,table
和 setof
类型是等价的,
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 footype
与 RETURNS SETOF record
不同,因为现在它不再是“未知”类型。 footype
的列定义明确。
谢谢你,@PeterKrauss。 :-)以上是关于SQL 函数返回类型:TABLE vs SETOF 记录的主要内容,如果未能解决你的问题,请参考以下文章
在 WHILE LOOP 部分之后从 PostgreSQL 函数返回 SETOF 行
怎样用sql server自定义函数,实现动态的sql,返回一个table类型