PostgreSQL:如何区分存储过程和表值函数?

4
问题:
在 Microsoft SQL Server 中,有存储过程和表值函数。
区别在于,从存储过程中,我不能做进一步的选择,而从表值函数中,我可以。
例如。
SELECT * FROM sp_whatever WHERE xxx 是非法的 而 SELECT * FROM TVF_whatever WHERE xxx 是完全合法的
现在我的问题是:
在 PostgreSQL 中,当我查看 information_schema.routines 时,如何区分表值函数和过程?
是否有任何差异?
而且通常情况下,如何在 PostgreSQL 中区分函数和过程?
我的意思是理论上,对于 SQL Server,可以这样区分它们: 表值函数: information_schema.data_type = 'table' 存储过程: information_schema.data_type IS NULL 函数: information_schema.data_type != 'table' AND information_schema.data_type IS NOT NULL
在 Postgres 中如何实现?
理论上,存储过程具有返回类型 void,但由于存储过程也可以返回表格,因此无法区分 tvf 和存储预处理程序——假设存在区别。
因此,我的问题也可以这样表述: 在 PostGreSQL 中,如何创建表值函数,以及如何创建存储过程(每个示例1个)。
我对两者之间返回类型的差异很感兴趣。
1个回答

3

PostgreSQL没有真正的存储过程,只有用户定义的函数:

CREATE FUNCTION foo() RETURNS TABLE(bar INT, baz TEXT) ...

CREATE FUNCTION bar() RETURNS BOOLEAN ...

检查"record"数据类型:

SELECT * FROM information_schema.routines WHERE data_type = 'record';

所以,您是说,在 pgsql 中,返回一个 select 的“存储过程”与表值函数完全等效吗?或者是否有一种定义返回类型的方式,使其仍然是表,但不能用于进一步的 select 和 join,就像存储过程的结果一样? - Stefan Steiger
您可以始终在其他查询和/或函数中使用函数的结果,完全没有问题。 - Frank Heikens
1
@Quandary,你所描述的后一点,即返回一个不能(直接)被其他过程/函数使用的结果,可以通过返回 refcursor 来实现。请参见 http://www.postgresql.org/docs/current/static/plpgsql-cursors.html 。然后调用者从游标中 FETCH 结果。不过,老实说,你通常应该只使用返回表格的函数,即返回 SETOF something 的函数。 - Craig Ringer
4
关于等效性,更多的是因为PostgreSQL中没有存储过程。一切都是通过可调用SQL函数完成的。这实际上唯一的限制是你不能直接返回多个结果集(尽管可以通过refcursors实现),以及你不能在函数内开始/提交事务。 - Craig Ringer
1
“CREATE FUNCTION foo() RETURNS TABLE(bar INT)”并不产生“data_type ='record'”,而是产生“data_type ='int'”。所以这并不是那么简单的事情... - Lukas Eder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接