Postgresql 如何将表参数传递到此函数?

Postgresql 如何将表参数传递到此函数?,postgresql,casting,plpgsql,Postgresql,Casting,Plpgsql,我有一个这样组织的功能: create function everything(waypoints waypoint) returns table(node int, xy text array) as $$ BEGIN create view results as ... return query (select * from results); END; $$ LANGUAGE plpgsql; 我有一个表,它的参数按照航路点数据类型的结构进行组织。此表本身不是明确的

我有一个这样组织的功能:

create function everything(waypoints waypoint)
  returns table(node int, xy text array) as $$
BEGIN
    create view results as ...

    return query (select * from results);
END;
$$ LANGUAGE plpgsql;
我有一个表,它的参数按照航路点数据类型的结构进行组织。此表本身不是明确的航路点类型

函数按其应该的方式创建,但是,我无法通过如下方式传入我的表来调用它:

选择所有航路点

或者从temp中选择everythingselect*

但它表示,后者在select或select附近出现语法错误,前者不存在列航路点

如何继续?

如果waypoint和temp中的所有类型都可转换为文本,则您可以序列化为文本并从文本反序列化:

但是,明确的构造将更干净:

SELECT  everything((col1, col2, col3, ...)::waypoint)
FROM    temp
或创建演员阵容:


所有的东西都经过了9.4级的测试

Postgres在处理行类型的语法上有一些弱点。不能直接从表别名强制转换:

SELECT w::waypoint FROM waypoints w;
解决方案只有一步之遥:在子查询中分解行,然后转换工作。通过这种方式,列值被分解并直接包装到新类型中,而无需转换为文本和返回。无需单独列出所有列,也无需创建自定义强制转换:

SELECT (w.*)::waypoint FROM (SELECT * FROM waypoints) w;
或更短:

SELECT w.*::waypoint FROM (TABLE waypoints) w;
或更短,但:

SELECT w::waypoint FROM (TABLE waypoints) w;
在一个有30k行和简单类型的快速测试中,这比文本和文本转换快10倍。如果您有大的jsonb列或任何复杂类型的文本转换,两者之间的差异会更大

更重要的是,您不需要另一个自定义复合行类型。每个表都已自动将其行定义为类型。只要尽可能使用现有类型的航路点,而不是航路点。那么你所需要的就是:

SELECT w FROM waypoints w;
或者,举个例子:

SELECT everything(t) FROM temp t;  -- using type waypoints
SELECT everything(t::waypoint) FROM (TABLE temp) t;  -- using type waypoint
旁白:

表没有参数,只有列。 您不是向该函数传递表参数,而是传递行值。这就是按名称传递表的方式:

不能在Postgres中直接将整个表作为参数传递,因为没有表变量。您可以使用游标或临时表来进行此操作

作用 您的函数具有无效的类型声明,并且不必要地复杂。我严重怀疑您是否想创建一个视图:

CREATE FUNCTION everything(_wp waypoint)  -- or use type waypoints
  RETURNS TABLE(node int, xy text[]) AS
$func$
BEGIN
   RETURN QUERY
   SELECT ...
END
$func$ LANGUAGE plpgsql;
文本数组语法无效,使用text[]来声明文本数组

不要将表/类型名称waypoints用作函数参数名称,否则会导致混淆错误

或者,如果您的案例非常简单,只需使用简单的SQL函数即可:

CREATE FUNCTION everything(_wp waypoint)  -- or use type waypoints
  RETURNS TABLE(node int, xy text[]) AS
$func$
   SELECT ...
$func$ LANGUAGE sql;

不要引用语言名称。它是一个标识符。

你是说temp::text::waypoint正确吗?由于waypoint是数据类型?另一个问题,不相关,但我一直看到:无法删除表图,因为此会话中的活动查询正在使用它,而此表用于生成结果,它是在我尝试删除它后立即创建的。我怎样才能解决这个问题?@Louis93:请把它作为一个单独的问题发布。为什么不让所有的东西都马上接受临时工呢?创建函数所有路径点温度。。。等等。请始终提供您的Postgres版本。你的问题有点不清楚。我是否正确地理解了您想要将整个表行强制转换为预定义的复合行类型?嘿,这是一篇非常出色的文章,非常感谢。但是,当我运行此命令时:从表temp t中选择Everything.*::waypoint;我得到:关系wp不存在`。。。为什么会发生这种情况?@Louis93:_wp是我示例中的函数参数名。看起来动态SQL出错了。既然函数体是你的秘密,我只能猜测。我建议你发布一个新的问题,包括必要的细节。我给了你最好的答案,因为它信息量最大。这里有一个新的问题和必要的细节:期待您的意见。
SELECT everything(t) FROM temp t;  -- using type waypoints
SELECT everything(t::waypoint) FROM (TABLE temp) t;  -- using type waypoint
CREATE FUNCTION everything(_wp waypoint)  -- or use type waypoints
  RETURNS TABLE(node int, xy text[]) AS
$func$
BEGIN
   RETURN QUERY
   SELECT ...
END
$func$ LANGUAGE plpgsql;
CREATE FUNCTION everything(_wp waypoint)  -- or use type waypoints
  RETURNS TABLE(node int, xy text[]) AS
$func$
   SELECT ...
$func$ LANGUAGE sql;