Postgres - 错误:操作符不存在。

6

我有一个在本地运行良好的函数,但是将其移动到线上却出现了一个大错误... 从一个回答中得到启示,其中有人指出我传递的参数数量不准确,我在这种情况下再次仔细检查,确保我向函数本身传递了5个参数...

Query failed: ERROR: operator does not exist: point <@> point HINT: No operator matches the given name and argument type(s). You may need to add explicit type casts.

这是查询的内容:
BEGIN; SELECT zip_proximity_sum('zc',                                                                                                                                                                  
    (SELECT g.lat FROM geocoded g                                                                                                                                                                              
    LEFT JOIN masterfile m ON g.recordid = m.id                                                                                                                                                                
    WHERE m.zip = '10050' ORDER BY m.id LIMIT 1),                                                                                                                                                             
    (SELECT g.lon FROM geocoded g                                                                                                                                                                              
    LEFT JOIN masterfile m ON g.recordid = m.id                                                                                                                                                                
    WHERE m.zip = '10050' ORDER BY m.id LIMIT 1),                                                                                                                                                             
    (SELECT m.zip FROM geocoded g                                                                                                                                                                              
    LEFT JOIN masterfile m ON g.recordid = m.id                                                                                                                                                                
    WHERE m.zip = '10050' ORDER BY m.id LIMIT 1)                                                                                                                                                              
    ,10);

PG函数是这样的:
CREATE OR REPLACE FUNCTION zip_proximity_sum(refcursor, numeric, numeric, character, numeric)
  RETURNS refcursor AS
$BODY$ 
    BEGIN 

        OPEN $1 FOR 
            SELECT r.zip, point($2,$3) <@> point(g.lat, g.lon) AS distance
            FROM
            geocoded g LEFT JOIN masterfile r ON g.recordid = r.id 
            WHERE (geo_distance( point($2,$3),point(g.lat,g.lon)) < $5)
            ORDER BY r.zip, distance;
        RETURN $1; 
    END; 
    $BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;

1
抱歉如果这听起来有点严厉,但你真的读了错误信息吗? - Frank Bollack
你最终搞清楚了发生了什么吗?我也遇到了同样的问题。已经安装并验证了cubeearthdistance扩展,重启了PostgreSQL。但是出现了[42883] ERROR: operator does not exist: point <@> point错误。这可能与Windows上的PostgreSQL v11有关吗? - thames
7个回答

11

这里是确切的命令:

create extension cube;
create extension earthdistance;
select (point(-0.1277,51.5073) <@> point(-74.006,40.7144)) as distance;

     distance     
------------------
 3461.10547602474
(1 row)

请注意,points 的创建是先经度再纬度。根据文档

之所以采用 (经度, 纬度) 而不是 (纬度, 经度),是因为经度更接近于 x 轴的直观概念,而纬度则更接近 y 轴。

虽然这种设计很糟糕...但就是这样。


这个不起作用。cubeearthdistance都已经安装并通过pg_available_extensions进行了验证。重新启动了PostgreSQL。[42883] ERROR: operator does not exist: point <@> point。可能是Windows上的PostgreSQL v11的问题?是的,Long/Lat的顺序正确。 - thames
这不是一个糟糕的设计,而是默认设置。Postgis默认使用经纬度。我们通常谈论x,y,而在这种情况下分别是经度和纬度。 - Kevin Potgieter

4

是的,但它仍然会抛出错误。cubeearthdistance 都已安装并通过 pg_available_extensions 进行了验证。已重新启动 PostgreSQL。[42883] ERROR: operator does not exist: point <@> point。可能是 Windows 上的 PostgreSQL v11 的问题? - thames

1

1

你确定在线服务器上已经正确安装了PostGIS吗?


1

您需要在pg_catalog模式下创建扩展,以便这些扩展可以全局使用。请执行以下命令:

  • 如果存在,则删除earthdistance扩展;
  • 如果存在,则删除cube扩展;
  • 在pg_catalog模式下创建cube扩展;
  • 在pg_catalog模式下创建earthdistance扩展;

这个问题有点老(10年了),所以我不知道你的答案是否仍然相关。 - stateMachine
这对我很有帮助,感谢您指出模式参数! - green.maru

1
这是解决问题的步骤:
  1. 运行以下命令来检查扩展程序(cubeearthdistance)。
SELECT * FROM pg_available_extensions ORDER BY "name"
  1. 如果列表中仍然显示两个扩展名(cubeearthdistance),请运行以下命令:
CREATE EXTENSION cube;
CREATE EXTENSION earthdistance;
  1. 创建表并插入值
  • 创建位置表
CREATE TABLE location (
    id serial PRIMARY KEY,
    name varchar(50) NOT NULL,
    longitude double precision NOT NULL,
    latitude double precision NOT NULL
);

插入一些数据(#CHA周围的站点)
INSERT INTO location(name, latitude, longitude)
VALUES ('SupplyHog HQ', 35.0472780, -85.3071590)
,('Chickamauga Dam', 35.0975557,-85.2197027)
,('Five Points Mtn Biking', 34.851249, -85.423983)
,('Harrison Bay State Park', 35.179631, -85.114359)
,('Mojo Burrito', 35.0094040,-85.3275640)
,('Rock Creek', 35.0556150,-85.2803290);
  1. 运行选择查询,您将获得结果
  • 创建点时,使用point(long, lat)
SELECT *, point(-85.3078294, 35.0609500) <@> point(longitude, latitude)::point as distance 
FROM location
WHERE (point(-85.3078294, 35.0609500) <@> point(longitude, latitude)) < 10
ORDER BY distance;

0
错误点是你存储过程中的选择语句:
SELECT r.zip, point($2,$3) <@> point(g.lat, g.lon) AS distance
                            ^

在标记位置处需要一个运算符,但您的运算符未定义或具有其他参数类型。Postgres本身只知道<@@>包含运算符。请单击此处查看它们的说明。
请问您能否详细说明您想要实现什么。

回答不够有帮助。cubeearthdistance都已经安装并通过pg_available_extensions进行了验证。重新启动了PostgreSQL。[42883] ERROR: operator does not exist: point <@> point。可能是Windows上的PostgreSQL v11存在问题?是的,纬度/经度顺序正确(先是经度)。 - thames

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接