tin*_*lyx 8 postgresql set-returning-functions postgresql-9.5
还有另一种方法可以将函数声明为返回一个集合,即使用语法 RETURNS TABLE(columns)。... 这种表示法是在 SQL 标准的最新版本中指定的,因此可能比使用 SETOF 更具可移植性。
这听起来好像RETURNS TABLE
是返回多行的更新、更便携的样式。但我不确定这两种语法是否等效。
我想知道我们是否真的可以RETURNS TABLE
用来代替 RETURNS SETOF
?
特别是,我还没有弄清楚的一种情况是:如果我们有一个现有的表foo
及其关联的复合类型,我们如何在 中使用它RETURNS TABLE
?
使用上述链接的示例,可以使用以下内容重写RETURNS TABLE
:
CREATE TABLE foo (fooid int, foosubid int, fooname text);
CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;
Run Code Online (Sandbox Code Playgroud)
到目前为止,我尝试使用RETURNS TABLE (foo.*)
and RETURNS TABLE (foo)
,但没有用。
PS:抱歉我的评论,我正在开发一个复杂的代码,我有一个小错误,似乎是PostgreSQL对“返回表”部分的愚蠢限制......我很愚蠢,而不是集中精力解决它,我使用了互联网(搜索引擎把我放在这里)。现在,这个wiki-answer是为了帮助其他被搜索引擎调用并被问题标题所吸引的读者。
感谢@dezso(是一个正确的答案),请所有读者,您可以编辑此问题以使其更具教学性,它是一个 Wiki。
在其指南中,在所有 PostgreSQL 版本中,从pg v8到当前版本,都有一个名为 “SQL 函数作为表源”的部分。让我们通过一些简化重现指南的示例:
CREATE TABLE foo (fooid int, foosubid int, fooname text);
INSERT INTO foo VALUES (1, 1, 'Joe'), (1, 2, 'Ed'), (2, 1, 'Mary');
CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;
SELECT * FROM getfoo(1);
Run Code Online (Sandbox Code Playgroud)
它按预期运行,非常完美!
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
1 | 2 | Ed
Run Code Online (Sandbox Code Playgroud)
问题“如何将 RETURNS TABLE 与 PostgreSQL 中的现有表一起使用?” 自 pg v8 以来有一个很好的答案......这是我们在过去 15 年中的做法
RETURNS SETOF <EXISTING_TABLE_NAME>
,语法是: .
@tinlyx 的混淆,在他的问题中解释,是关于使用子句TABLE
而不是SETOF
......要考虑使用“PostgreSQL 语法逻辑”,我们必须首先记住这RETURN <EXISTING_TABLE_NAME>
也是有效的,并且它具有相同的行为RETURN <EXISTING_TYPE_NAME>
。很自然的只返回一行。
下一步,请记住我们使用 CREATE TABLE 子句 (<tuple_description>) 声明了一个元组,因此,表达“即时定义元组表”的好语法是 RETURN TABLE (<tuple_description>),并且return TABLE 类型,类似于数组类型,将返回多个实例(TABLE 是一组元组)。
下一步,请记住我们用子句声明了一个元组CREATE TABLE (<tuple_description>)
,因此,表达“即时表定义”的好语法是RETURN TABLE (<tuple_description>)
;并且返回 Table-type 是有意义的,就像 Array-type 一样,它们返回多个实例(TABLE 是一组元组)。
PostgreSQL (!) 中的“现代事物”就是@ZiggyCrueltyfreeZeitgeister 所展示的RETURNS TABLE (LIKE <table_name>)
语法。
CREATE FUNCTION getfoo2(int) RETURNS TABLE (LIKE foo) AS $$ -- working fine!
SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;
SELECT * FROM getfoo2(1); -- same result as getfoo(1)
Run Code Online (Sandbox Code Playgroud)
显式表名(两种方式)或类型名:
RETURNS TABLE (LIKE <table_name>)
(现代和好)RETURNS SETOF <table_name>
(老但是好)RETURNS SETOF <type_name>
(之后 CREATE TYPE <type_name> (<tuple_description>)
)隐式/通用方式,匿名类型:
RETURNS SETOF RECORD
(通用但有时有问题)RETURNS SETOF ROW?
瞬时表定义:
RETURNS TABLE (<tuple_description>)
RETURNS
)OUT
在参数列表中使用。对于最后一种情况,用我们的例子来说明: CREATE FUNCTION getfoo(int, OUT fooid int, OUT foosubid int, OUT fooname text)
对于动态和/或多态输入,您必须查看此说明。
有很多方法可以做同样的事情,那么,有一个“最好的”吗?
作为语法,我更喜欢使用RETURNS TABLE (LIKE <table_name>)
,这是明确的:不要与“隐式记录”混淆,不用担心不兼容......
对于库管理很重要,DROP TABLE foo CASCADE
也会删除功能:在任何语法(returns table
或returns setof
)中,PostgreSQL 都会做得很好。
drop table foo cascade;
NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to function getfoo(integer)
drop cascades to function getfoo2(integer)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6088 次 |
最近记录: |