批量修正无小数点GPS坐标,实现SDO_GEOMETRY地图全展示
解决GPS数据批量转换与空间字段更新问题
一、批量修正现有无小数点的GPS数据
针对70000条无小数点的经纬度记录,需先将其转换为正确的小数格式(假设原始整数是真实值乘以10000得到,如501234对应50.1234),再批量更新location字段。
1. 一次性批量更新(适合允许短时间锁表的场景)
UPDATE sitetb_gps SET location = SDO_GEOMETRY( 2001, 4326, SDO_POINT_TYPE( CASE WHEN MOD(longtitude, 1) = 0 THEN longtitude / 10000 ELSE longtitude END, CASE WHEN MOD(latitude, 1) = 0 THEN latitude / 10000 ELSE latitude END, NULL ), NULL, NULL ) WHERE latitude IS NOT NULL AND longtitude IS NOT NULL -- 仅更新未转换的整数格式记录 AND (MOD(latitude, 1) = 0 OR MOD(longtitude, 1) = 0); COMMIT;
2. 分批更新(避免锁表,适配大数量级数据)
若一次性更新导致锁表或性能问题,可分批次执行:
DECLARE v_count NUMBER := 1; BEGIN WHILE v_count > 0 LOOP UPDATE sitetb_gps SET location = SDO_GEOMETRY( 2001, 4326, SDO_POINT_TYPE( CASE WHEN MOD(longtitude, 1) = 0 THEN longtitude / 10000 ELSE longtitude END, CASE WHEN MOD(latitude, 1) = 0 THEN latitude / 10000 ELSE latitude END, NULL ), NULL, NULL ) WHERE latitude IS NOT NULL AND longtitude IS NOT NULL AND (MOD(latitude, 1) = 0 OR MOD(longtitude, 1) = 0) AND ROWNUM <= 1000; v_count := SQL%ROWCOUNT; COMMIT; END LOOP; END; /
二、修改自动更新逻辑(确保后续数据正确处理)
调整现有Apex单条更新语句,使其自动识别并转换整数格式的经纬度,保证新增/修改数据都能生成正确的空间字段:
修改后的单条更新语句
UPDATE sitetb_gps SET location = SDO_GEOMETRY( 2001, 4326, SDO_POINT_TYPE( -- 自动转换经度:整数则除以10000,否则直接使用 CASE WHEN MOD(longtitude, 1) = 0 THEN longtitude / 10000 ELSE longtitude END, -- 自动转换纬度 CASE WHEN MOD(latitude, 1) = 0 THEN latitude / 10000 ELSE latitude END, NULL ), NULL, NULL ) WHERE latitude IS NOT NULL AND longtitude IS NOT NULL AND rowid = :P1061_ROWID; COMMIT;
可选:用触发器实现自动更新(更高效)
若希望latitude/longtitude变更时自动同步location,可创建触发器:
CREATE OR REPLACE TRIGGER trg_sitetb_gps_update_location BEFORE INSERT OR UPDATE OF latitude, longtitude ON sitetb_gps FOR EACH ROW WHEN (NEW.latitude IS NOT NULL AND NEW.longtitude IS NOT NULL) BEGIN :NEW.location := SDO_GEOMETRY( 2001, 4326, SDO_POINT_TYPE( CASE WHEN MOD(:NEW.longtitude, 1) = 0 THEN :NEW.longtitude / 10000 ELSE :NEW.longtitude END, CASE WHEN MOD(:NEW.latitude, 1) = 0 THEN :NEW.latitude / 10000 ELSE :NEW.latitude END, NULL ), NULL, NULL ); END; /
关键说明
- 若无小数点的经纬度是真实值乘以其他倍数(如1000),需将
/10000替换为对应数值。 - 若
latitude/longtitude为字符串类型,判断整数的逻辑需调整为INSTR(latitude, '.') = 0,转换时用TO_NUMBER(latitude)/10000。
内容的提问来源于stack exchange,提问作者Steffen
相关产品推荐
相关产品推荐

