我想计算两个城市之间的距离。我有以下功能:
CREATE OR REPLACE FUNCTION calc_distance_for_cities(fromCityId bigint, toCityId bigint) RETURNS integer LANGUAGE plpgsql as $$
DECLARE
fromCityCoords Geometry;
toCityCoords Geometry;
BEGIN
SELECT * FROM geo_cities WHERE geo_cities.id = fromCityId RETURNING coords INTO fromCityCoords;
SELECT * FROM geo_cities WHERE geo_cities.id = toCityId RETURNING coords INTO toCityCoords;
SELECT ST_Distance(fromCityCoords, toCityCoords, true)
END;
$$
我做错了什么?
答案 0 :(得分:0)
TL; DR你"做错了"两件事:returns integer
应为returns float
,最后select ..
应为return ..
。
详细说明:
RETURN
从PL / pgSQL函数返回一个值 - 您需要使用它而不是最后SELECT
。 st_distance(..)
根据http://postgis.refractions.net/docs/ST_Distance.html返回float
值,因此您的第一行需要returns float
。
试试这个:
CREATE OR REPLACE FUNCTION calc_distance_for_cities(fromCityId bigint, toCityId bigint) RETURNS float LANGUAGE plpgsql as $$
DECLARE
fromCityCoords Geometry;
toCityCoords Geometry;
BEGIN
SELECT coords INTO fromCityCoords FROM geo_cities WHERE geo_cities.id = fromCityId;
SELECT coords INTO toCityCoords FROM geo_cities WHERE geo_cities.id = toCityId;
RETURN ST_Distance(fromCityCoords, toCityCoords, true);
END;
$$;
此外,这个函数实际上并不需要PL / pgSQL语言,并且可以在纯SQL中轻松实现,CTE(https://www.postgresql.org/docs/current/static/queries-with.html):
create or replace function calc_distance_for_cities(int8, int8) returns float as $$
with _from(city_coords) as (
select coords from geo_cities where geo_cities.id = $1
), _to(city_coords) as (
select coords from geo_cities where geo_cities.id = $2
)
select st_distance(_from.city_coords, _to.city_coords)
from _from, _to;
$$ language sql;
甚至没有CTE:
create or replace function calc_distance_for_cities(int8, int8) returns float as $$
select st_distance(
(select coords from geo_cities where geo_cities.id = $1),
(select coords from geo_cities where geo_cities.id = $2)
);
$$ language sql;