如何在PostgreSQL复合类型字面量中指定PostGIS geography值?
正确指定PostGIS geography值到自定义复合类型的方法
这个问题我之前处理过,你遇到的错误核心原因很明确:你把ST_GeogFromText函数调用当成字符串字面量传递给复合类型了。当你用::place强制转换字符串时,PostgreSQL不会执行字符串里的函数,而是会把整个内容当作地理数据的文本表示去解析,而ST_GeogFromText('POINT(...)')本身并不是合法的WKT(Well-Known Text)格式,所以才会报解析错误。
下面给你两种可行的解决方法:
方法一:直接用ROW()构造复合类型(推荐)
这种方式最直观,也不容易出错——直接调用地理函数生成geography对象,再用ROW()组装成你的自定义类型:
SELECT ROW('name', ST_GeogFromText('POINT(121.560800 29.901200)'))::place;
PostgreSQL会先执行ST_GeogFromText得到正确的地理对象,再把它和name字段一起打包成place类型的值,完全符合预期。
方法二:使用WKT字面量转换字符串
如果你一定要用字符串字面量的方式转换,需要把地理部分换成纯WKT格式,而不是函数调用。因为PostgreSQL在解析复合类型的字符串表示时,会自动把符合格式的文本转换成对应的地理类型(前提是你的复合类型字段已经定义为geography(point,4326)):
SELECT $$("name", 'POINT(121.560800 29.901200)')$$::place;
这里的'POINT(...)'是标准的WKT字符串,PostgreSQL能直接识别并转换成geography对象,不会出现解析错误。
额外验证
你可以单独测试这两种方法的结果:
-- 验证方法一的结果 SELECT (ROW('name', ST_GeogFromText('POINT(121.560800 29.901200)'))::place).location; -- 验证方法二的结果 SELECT ($$("name", 'POINT(121.560800 29.901200)')$$::place).location;
这两个查询都会返回正确的geography对象,和你单独执行SELECT ST_GeogFromText('POINT(121.560800 29.901200)')的结果一致。
内容的提问来源于stack exchange,提问作者hgl
相关产品推荐
相关产品推荐

