-- 删除现有的虚拟列 ALTER TABLE hzscreen_record DROPCOLUMN geom_linestring;
-- 创建支持多种几何类型的虚拟列 ALTER TABLE hzscreen_record ADDCOLUMN geom_geometry GEOMETRY AS ( CASE WHEN JSON_EXTRACT(xcgj, '$.geometry.type') ='LineString'THEN ST_GeomFromGeoJSON(JSON_UNQUOTE(JSON_EXTRACT(xcgj, '$.geometry'))) WHEN JSON_EXTRACT(xcgj, '$.features[0].geometry.type') ='LineString'THEN ST_GeomFromGeoJSON(JSON_UNQUOTE(JSON_EXTRACT(xcgj, '$.features[0].geometry'))) WHEN JSON_EXTRACT(xcgj, '$.features[0].geometry.type') ='MultiLineString'THEN ST_GeomFromGeoJSON(JSON_UNQUOTE(JSON_EXTRACT(xcgj, '$.features[0].geometry'))) ELSENULL END ) STORED;
-- 最保险的办法,可以处理 NULL 的情况 ALTER TABLE hzscreen_record ADDCOLUMN geom_geometry GEOMETRY AS ( CASE WHEN xcgj ISNOT NULL AND JSON_VALID(xcgj) =1 AND ( JSON_EXTRACT(xcgj, '$.geometry') ISNOT NULL OR JSON_EXTRACT(xcgj, '$.features[0].geometry') ISNOT NULL OR JSON_EXTRACT(xcgj, '$.type') IN ('LineString', 'MultiLineString') ) THEN ST_GeomFromGeoJSON( JSON_UNQUOTE( COALESCE( JSON_EXTRACT(xcgj, '$.geometry'), JSON_EXTRACT(xcgj, '$.features[0].geometry'), CASE WHEN JSON_EXTRACT(xcgj, '$.type') IN ('LineString', 'MultiLineString') THEN xcgj ELSENULL END, '{"type":"Point","coordinates":[0,0]}' ) ) ) ELSE NULL END ) STORED;
3.创建索引
使用这个创建索引,会出现:SQL 错误 [1252] [42000]: All parts of a SPATIAL index must be NOT NULL
1
CREATE INDEX idx_geom_geometry ON hzscreen_record(geom_geometry);
【解决方案】 (1)添加约束
1 2 3 4 5 6 7 8 9
-- 更新NULL值为有效的JSON UPDATE hzscreen_record SET xcgj ='{"type":"Feature","geometry":{"type":"Point","coordinates":[0,0]}}' WHERE xcgj ISNULLOR JSON_VALID(xcgj) =0;
-- 创建新的虚拟列,处理NULL情况 ALTER TABLE hzscreen_record ADDCOLUMN geom_geometry GEOMETRY AS ( CASE WHEN xcgj ISNOT NULL AND JSON_VALID(xcgj) =1 AND ( JSON_EXTRACT(xcgj, '$.geometry') ISNOT NULL OR JSON_EXTRACT(xcgj, '$.features[0].geometry') ISNOT NULL ) THEN ST_GeomFromGeoJSON( JSON_UNQUOTE( COALESCE( JSON_EXTRACT(xcgj, '$.geometry'), JSON_EXTRACT(xcgj, '$.features[0].geometry') ) ) ) ELSE ST_GeomFromText('POINT(0 0)', 4326) -- 默认几何,确保不为NULL END ) STORED NOT NULL;
-- 现在应该可以创建索引了 CREATE INDEX idx_geom_geometry ON hzscreen_record(geom_geometry);
-- 检查虚拟列是否正常工作 SELECT COUNT(*) as total_records, COUNT(geom_geometry) as records_with_geometry, MIN(ST_AsText(geom_geometry)) as sample_geometry FROM hzscreen_record;
-- 查询操作 SELECT id, xcgj FROM hzscreen_record WHERE geom_geometry ISNOT NULL AND MBRIntersects( geom_geometry, ST_GeomFromText('POLYGON((0 -1, 1 -1, 1 1, 0 1, 0 -1))', 4326) ) LIMIT 5;