昨天在网上搜了一些城市的经纬度非完整资料,想把他们添加到oracle中,折腾了半天终于完成了。无奈下班时把 pl/sql developer 关掉时没保存sql 代码。那个郁闷啊......今天就不重写昨天的内容了。
简要的阐述一下过程吧:
1 导入数据
网上搜到的资料就是一个普通的文本,想要弄到数据库中,要么通过一条一条对应手工录入,要么通过什么导入吧,比如excel 什么的。结果还真有方法 把文本copy 到excel 中数据成了一行一行的"结构化数据"了,然后把表打开成编辑状态点击相应表头,这样就选择了这一整列,然后粘贴,搞定。
2 调整数据
copy 进来的数据因为城市顺序与数据库中的城市顺序不一致所以还的调整。 数据格式形如形如 "牡丹江 129.34 44.35";
思路很简单 如果名字相配则切割字符串后update.
写一个测试sql , 列des中正是保存 copy 进去的数据。
update (select m.cityid ,m.des from s_city m join s_city s on m.cityname = substr( s.des,1, instr(s.des,' ',1)-1)|| '市')
t set t.des = t.des;
执行错误,错误信息"无法保存非键值保存表对应的列"。添加主键后还是错误,并且 select 出来的结果集也没有重复数据。无语了,不知道什么原因。
通过一条语句实现有障碍,就两条吧经度纬度分别update。最终搞定。
今天的内容:
获得弧度的函数。
CREATE OR REPLACE FUNCTION RAD(d number) RETURN NUMBER
is
PI number :=3.141592625;
begin
return d* PI/180.0;
end ;
select RAD(360) from dual;
根据经纬度计算距离。
CREATE OR REPLACE FUNCTION GetDistance(lat1 number,
lng1 number,
lat2 number,
lng2 number) RETURN NUMBER is
earth_padius number := 6378.137;
radLat1 number := rad(lat1);
radLat2 number := rad(lat2);
a number := radLat1 - radLat2;
b number := rad(lng1) - rad(lng2);
s number := 0;
begin
s := 2 *
Asin(Sqrt(power(sin(a / 2), 2) +
cos(radLat1) * cos(radLat2) * power(sin(b / 2), 2)));
s := s * earth_padius;
s := Round(s * 10000) / 10000;
return s;
end;
--根据城市名计算距离
CREATE OR REPLACE FUNCTION GetDisByCityName(str1 varchar2, str2 varchar2)
return number is
lat1 number := 0;
lng1 number := 0;
lat2 number := 0;
lng2 number := 0;
begin
select longitude into lat1 from s_city where cityname=str1 ;
select dimensionality into lng1 from s_city where cityname=str1;
select longitude into lat2 from s_city where cityname=str2;
select dimensionality into lng2 from s_city where cityname=str2;
return GetDistance(lat1 ,lng1 ,lat2 , lng2 );
end;
--select GetDisByCityName('长沙市','南昌市')from dual;
结果 258.6275