PL/PGSQL 总是 returns 数组或数组列表

PL/PGSQL always returns array or list of arrays

给定简单的 pl/pgsql 函数:

CREATE OR REPLACE FUNCTION foo (point geometry
                              , OUT _street text
                              , OUT _gid int
                              , OUT distance real)
AS $$
BEGIN 

    SELECT min(distance(point,geom)) as dist, gid, name into distance, _gid, _street
    from streets 
    where geometria && Expand(point,0.001) group by gid, name order by dist limit 1;

END;
$$ LANGUAGE plpgsql;

结果类似于:

 geobase=# select foo(GeomFromText('POINT(-99.124191496999 19.3490666368031)',4326));
                      foo                      
 -------------------------------------------------
 ("PASEO DE LOS FRAMBOYANES",345483,0.000118338)

这很好,除了我期待更类似于此的事实:

          _street         |  _gid  |  distance     
--------------------------+--------+-------------
 PASEO DE LOS FRAMBOYANES | 345483 | 0.000118338

我尝试了 RETURN 子句的变体,将其定义为行类型、记录甚至 table,但我总是得到示例中所示的元组或数组。关于如何以类似于 table?

的方式获得结果的任何线索

尝试select * from foo(GeomFromText('POINT(-99.124191496999 19.3490666368031)',4326)); ?..

问的问题已经回答了很多次了。分解返回的行类型:

SELECT * FROM foo( ... );

点赞:


但还有更多。

您的函数具有更少的语法混乱、更不容易出错和简化:

CREATE OR REPLACE FUNCTION foo (_point geometry)
  RETURNS TABLE (street text, gid int, distance real)
  LANGUAGE plpgsql AS
$func$
BEGIN
   RETRUN QUERY 
   SELECT s.name, s.gid, distance(_point, s.geom)
   FROM   streets s
   WHERE  s.geometria && expand(_point, 0.001)
   ORDER  BY 3
   LIMIT  1;
END
$func$;

既然你有ORDER BY ... LIMIT 1,你根本不需要min()GROUP BY

请注意我如何 table 限定所有列以避免命名冲突。

一个细微差别:如果查询发现没有行你原来的returns一行用NULL值代替,而我的函数居然returns没有一行。通常,您会想要后者。

与等效的简单 SQL 函数相同:

CREATE OR REPLACE FUNCTION foo (_point geometry)
  RETURNS TABLE (street text, gid int, distance real)
  LANGUAGE sql AS
$func$
SELECT s.name, s.gid, distance(_point, s.geom)
FROM   streets s
WHERE  s.geometria && expand(_point, 0.001)
ORDER  BY 3
LIMIT  1;
$func$;

大 tables 仍然不是很有效。您会对 KNN(k 最近邻)在 PostGis 中搜索感兴趣:

  • Multicolumn index on 3 fields with heterogenous data types
  • Improving performance with a Similarity Postgres fuzzy self join query