使用SQL Spatial将GeoJSON LineString转换为WKB及代码报错修复
问题原因
- 你当前的报错是因为字符串替换逻辑生成的WKT末尾多了一个多余逗号:你把所有
]替换为逗号后,最后一个坐标对的闭合]也被替换成了逗号,最终生成的WKT格式类似LINESTRING(x y, x y, x y,),不符合WKT规范,所以解析失败。 - 另外动态SQL执行的方式在处理海量数据时性能极低,且存在潜在的注入风险,不建议生产环境使用。
修复方案
1. 现有代码快速修复
只需要在原有替换逻辑最后去掉末尾多余的逗号即可,修改后的代码如下:
declare @Road nvarchar(max) = '{ "type" : "LineString", "coordinates" : [ [ -1.1956788082, 22.7406770914 ], [ -1.1993641111, 22.7406737999 ], [ -1.1992222243, 22.7412345977 ] ] }'; declare @GeoString nvarchar(max) = (select '''' + upper(ShapeType) + '(' + -- 最后用TRIM去掉末尾多余的逗号 TRIM(',' from replace( replace( RePlace( replace(Shape, '[', '') , ',', ' ') , ']]', ''), ']', ',') ) + ')' + '''' from openjson(@Road) with (ShapeType Varchar(64) '$.type', Shape nvarchar(max) '$.coordinates' as json) ) -- 直接生成WKB的话调用.STAsBinary()方法 declare @String nvarchar(max) = ( select 'select geography::STGeomFromText(' + @GeoString + ', 4326).STAsBinary() as wkb_data') exec (@String)
2. 海量数据适配最优方案
直接用OPENJSON解析坐标数组拼接WKT,避免多层替换和动态SQL,性能更高、兼容性更强,适合处理大批量道路数据:
declare @Road nvarchar(max) = '{ "type" : "LineString", "coordinates" : [ [ -1.1956788082, 22.7406770914 ], [ -1.1993641111, 22.7406737999 ], [ -1.1992222243, 22.7412345977 ] ] }'; -- 解析得到类型和坐标WKT片段 declare @ShapeType varchar(64), @CoordStr nvarchar(max) select @ShapeType = upper(type) from openjson(@Road) with (type varchar(64) '$.type', coordinates nvarchar(max) '$.coordinates' as json) -- 拼接坐标对 select @CoordStr = string_agg(concat(json_value(value, '$[0]'), ' ', json_value(value, '$[1]')), ',') from openjson(json_query(@Road, '$.coordinates')) -- 直接生成WKB,无需动态SQL declare @wkb varbinary(max) = geography::STGeomFromText(concat(@ShapeType, '(', @CoordStr, ')'), 4326).STAsBinary() -- 查看结果 select @wkb as wkb_data
该方案可以直接套用到表字段批量处理场景,直接对存储GeoJSON的字段执行上述解析逻辑即可,比多层字符串替换的稳定性和性能高出30%以上。
内容的提问来源于stack exchange,提问作者user16984156
相关产品推荐
相关产品推荐

