postgres 函数/扩展未正确转储或恢复?
postgres functions / extensions not dumped or restored correctly?
更新
自我回答,请参阅此处的第一条评论和我自己的回答。
原题
我正在使用一些 sql 文件设置一个本地开发 postgres 数据库,其中一个文件创建了一个用于距离计算的自定义函数。已创建扩展 "cube" 和 "earthdistance",函数按预期工作。
我正在转储本地开发 postgres 数据库,sql 转储包含扩展创建和自定义函数 - 看起来不错。
我正在另一台测试机器上导入转储,没有出现错误消息。
但是我在使用函数时遇到异常:
Caused by: org.postgresql.util.PSQLException: ERROR: function ll_to_earth(numeric, numeric) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Where: PL/pgSQL function opengeodb_radius_selection(numeric,numeric,integer,integer) line 3 at RETURN QUERY
设置本地数据库时使用的完整SQL代码:
CREATE EXTENSION cube;
CREATE EXTENSION earthdistance;
CREATE FUNCTION
opengeodb_radius_selection(
baseLatitude numeric(9,6),
baseLongitude numeric(9,6),
radius_in_metres integer,
opengeodb_level integer)
RETURNS TABLE(
locid integer,
name character varying(255),
distance float8)
AS
$func$
BEGIN
RETURN QUERY
SELECT subQueryAlias.locid, subQueryAlias.name, subQueryAlias.distance
FROM
(
SELECT *, earth_distance(ll_to_earth(baseLatitude,baseLongitude), ll_to_earth(lat,lon)) as distance
FROM opengeodb
GROUP BY opengeodb.locid, opengeodb.lat, opengeodb.lon, opengeodb.name, distance
) subQueryAlias
WHERE plz is not null
AND plz <> ''
AND level = opengeodb_level
AND earth_box(ll_to_earth(lat,lon),radius_in_metres) @> ll_to_earth(baseLatitude,baseLongitude)
AND subQueryAlias.distance <= radius_in_metres
ORDER BY subQueryAlias.distance;
END
$func$ LANGUAGE plpgsql;
转储中的完整 SQL 代码:
--
-- PostgreSQL database dump
--
SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner:
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner:
--
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
--
-- Name: cube; Type: EXTENSION; Schema: -; Owner:
--
CREATE EXTENSION IF NOT EXISTS cube WITH SCHEMA public;
--
-- Name: EXTENSION cube; Type: COMMENT; Schema: -; Owner:
--
COMMENT ON EXTENSION cube IS 'data type for multidimensional cubes';
--
-- Name: earthdistance; Type: EXTENSION; Schema: -; Owner:
--
CREATE EXTENSION IF NOT EXISTS earthdistance WITH SCHEMA public;
--
-- Name: EXTENSION earthdistance; Type: COMMENT; Schema: -; Owner:
--
COMMENT ON EXTENSION earthdistance IS 'calculate great-circle distances on the surface of the Earth';
SET search_path = public, pg_catalog;
--
-- Name: opengeodb_radius_selection(numeric, numeric, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres
--
CREATE FUNCTION opengeodb_radius_selection(baselatitude numeric, baselongitude numeric, radius_in_metres integer, opengeodb_level integer) RETURNS TABLE(locid integer, name character varying, distance double precision)
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY
SELECT subQueryAlias.locid, subQueryAlias.name, subQueryAlias.distance
FROM
(
SELECT *, earth_distance(ll_to_earth(baseLatitude,baseLongitude), ll_to_earth(lat,lon)) as distance
FROM opengeodb
GROUP BY opengeodb.locid, opengeodb.lat, opengeodb.lon, opengeodb.name, distance
) subQueryAlias
WHERE plz is not null
AND plz <> ''
AND level = opengeodb_level
AND earth_box(ll_to_earth(lat,lon),radius_in_metres) @> ll_to_earth(baseLatitude,baseLongitude)
AND subQueryAlias.distance <= radius_in_metres
ORDER BY subQueryAlias.distance;
END
$$;
ALTER FUNCTION public.opengeodb_radius_selection(baselatitude numeric, baselongitude numeric, radius_in_metres integer, opengeodb_level integer) OWNER TO postgres;
SET default_tablespace = '';
SET default_with_oids = false;
...(followed by table creation and so on)
这是我的错还是错误的行为?
ll_to_earth
被定义为采用参数 (float8, float8)
,但您传递的是 numeric, numeric
。所以你需要在你的函数中添加一些转换。
目前还不清楚为什么它以前有效。也许您是从旧版本升级的?
自我回答(见第一个问题评论)
在debian系统上安装了9.4.10,debian没有9.4.10的postgresql-contrib(但在我的开发中windows postgres包,也是9.4.10)
我们已经将 debian 系统更新到 9.4.12,现在包含了 contrib,功能正常。
更新
自我回答,请参阅此处的第一条评论和我自己的回答。
原题
我正在使用一些 sql 文件设置一个本地开发 postgres 数据库,其中一个文件创建了一个用于距离计算的自定义函数。已创建扩展 "cube" 和 "earthdistance",函数按预期工作。
我正在转储本地开发 postgres 数据库,sql 转储包含扩展创建和自定义函数 - 看起来不错。
我正在另一台测试机器上导入转储,没有出现错误消息。
但是我在使用函数时遇到异常:
Caused by: org.postgresql.util.PSQLException: ERROR: function ll_to_earth(numeric, numeric) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Where: PL/pgSQL function opengeodb_radius_selection(numeric,numeric,integer,integer) line 3 at RETURN QUERY
设置本地数据库时使用的完整SQL代码:
CREATE EXTENSION cube;
CREATE EXTENSION earthdistance;
CREATE FUNCTION
opengeodb_radius_selection(
baseLatitude numeric(9,6),
baseLongitude numeric(9,6),
radius_in_metres integer,
opengeodb_level integer)
RETURNS TABLE(
locid integer,
name character varying(255),
distance float8)
AS
$func$
BEGIN
RETURN QUERY
SELECT subQueryAlias.locid, subQueryAlias.name, subQueryAlias.distance
FROM
(
SELECT *, earth_distance(ll_to_earth(baseLatitude,baseLongitude), ll_to_earth(lat,lon)) as distance
FROM opengeodb
GROUP BY opengeodb.locid, opengeodb.lat, opengeodb.lon, opengeodb.name, distance
) subQueryAlias
WHERE plz is not null
AND plz <> ''
AND level = opengeodb_level
AND earth_box(ll_to_earth(lat,lon),radius_in_metres) @> ll_to_earth(baseLatitude,baseLongitude)
AND subQueryAlias.distance <= radius_in_metres
ORDER BY subQueryAlias.distance;
END
$func$ LANGUAGE plpgsql;
转储中的完整 SQL 代码:
--
-- PostgreSQL database dump
--
SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner:
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner:
--
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
--
-- Name: cube; Type: EXTENSION; Schema: -; Owner:
--
CREATE EXTENSION IF NOT EXISTS cube WITH SCHEMA public;
--
-- Name: EXTENSION cube; Type: COMMENT; Schema: -; Owner:
--
COMMENT ON EXTENSION cube IS 'data type for multidimensional cubes';
--
-- Name: earthdistance; Type: EXTENSION; Schema: -; Owner:
--
CREATE EXTENSION IF NOT EXISTS earthdistance WITH SCHEMA public;
--
-- Name: EXTENSION earthdistance; Type: COMMENT; Schema: -; Owner:
--
COMMENT ON EXTENSION earthdistance IS 'calculate great-circle distances on the surface of the Earth';
SET search_path = public, pg_catalog;
--
-- Name: opengeodb_radius_selection(numeric, numeric, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres
--
CREATE FUNCTION opengeodb_radius_selection(baselatitude numeric, baselongitude numeric, radius_in_metres integer, opengeodb_level integer) RETURNS TABLE(locid integer, name character varying, distance double precision)
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY
SELECT subQueryAlias.locid, subQueryAlias.name, subQueryAlias.distance
FROM
(
SELECT *, earth_distance(ll_to_earth(baseLatitude,baseLongitude), ll_to_earth(lat,lon)) as distance
FROM opengeodb
GROUP BY opengeodb.locid, opengeodb.lat, opengeodb.lon, opengeodb.name, distance
) subQueryAlias
WHERE plz is not null
AND plz <> ''
AND level = opengeodb_level
AND earth_box(ll_to_earth(lat,lon),radius_in_metres) @> ll_to_earth(baseLatitude,baseLongitude)
AND subQueryAlias.distance <= radius_in_metres
ORDER BY subQueryAlias.distance;
END
$$;
ALTER FUNCTION public.opengeodb_radius_selection(baselatitude numeric, baselongitude numeric, radius_in_metres integer, opengeodb_level integer) OWNER TO postgres;
SET default_tablespace = '';
SET default_with_oids = false;
...(followed by table creation and so on)
这是我的错还是错误的行为?
ll_to_earth
被定义为采用参数 (float8, float8)
,但您传递的是 numeric, numeric
。所以你需要在你的函数中添加一些转换。
目前还不清楚为什么它以前有效。也许您是从旧版本升级的?
自我回答(见第一个问题评论)
在debian系统上安装了9.4.10,debian没有9.4.10的postgresql-contrib(但在我的开发中windows postgres包,也是9.4.10)
我们已经将 debian 系统更新到 9.4.12,现在包含了 contrib,功能正常。