我正在尝试为Postgres 9.6编写一个函数来访问用C编写的一些代码。
我的功能定义为:
CREATE OR REPLACE FUNCTION graph_cluster_graph (sql text, has_rcost boolean)
RETURNS SETOF RECORD AS
'$libdir/libpgrouting-2.4', 'dir_graph_cluster_desc'
LANGUAGE c STABLE STRICT;
尝试使用以下方法调用它时:
select * from graph_cluster_graph('select * from case3_cab_dist_table',true);
我收到错误
返回“record
”的函数需要定义列表
如果我写
,它会起作用select graph_cluster_graph('select * from case3_cab_dist_table',true);
在这种情况下,它会调用请求的C函数,然后在返回时退出。
我确实更改了C函数的名称,只是为了找出会发生什么(你可能会因无法找到函数而出错)。所以我知道它可以找到我的C例程。再次使用select
语句的第二种形式并获得响应意味着已正确调用C函数。
有谁知道我做错了什么?
答案 0 :(得分:2)
使用RETURNS SETOF RECORD
函数,查询解析器不知道结果行将包含哪些列,并且您必须在查询中提供该信息。
就像the documentation所说的那样,
在某些情况下,定义可返回的表函数很有用 不同的列集取决于它们的调用方式。为了支持这一点, table函数可以声明为返回伪类记录。 在查询中使用此类函数时,必须使用预期的行结构 在查询本身中指定,以便系统可以知道如何解析 并计划查询。此语法如下所示:
function_call [AS] alias (column_definition [, ... ]) function_call AS [alias] (column_definition [, ... ]) ROWS FROM( ... function_call AS (column_definition [, ... ]) [, ... ] )
如果您事先知道记录将包含哪些列,最好将该函数定义为
RETURNS SETOF datatype
或
RETURNS TABLE ( column_name column_type [, ...] )
后者是旧语法的简写:
funcname(..., OUT column_name column_type, ...) RETURNS SETOF record