2016-05-19 17 views
0

都市とその経度および緯度を含む表があります。ある都市からこの表の他のすべての都市までのすべての距離を計算し、それらの距離を返す関数をPL/SQLに記述する必要があります。私はすでに2都市間の距離を計算する関数を作っています。私はカーソルで作業する必要があることを知っています。任意のヒント?ここでPL/SQLで1つの都市からすべての都市までの距離を計算する関数

 `CREATE TABLE Rheinland_Staedte 
     (Stadtname VARCHAR2(25), 
     Noerdlicher_Grad NUMBER, 
     Noerdliche_Minute NUMBER, 
     oestlicher_Grad NUMBER, 
     oestliche_Minute NUMBER, 
     CONSTRAINT rhein_St UNIQUE (Stadtname,Noerdlicher_Grad,Noerdliche_Minute,oestlicher_Grad,oestliche_Minute) 
    ); 


     INSERT INTO Rheinland_Staedte 
     VALUES ('Aachen',50,47,6,5); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Bonn',50,44,7,6); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Düsseldorf',51,14,6,47); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Duisburg',51,25,6,4); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Essen',51,27,7,1); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Köln',50,56,6,57); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Krefeld',51,20,6,34); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Leverkusen',51,2,6,59); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Mönchengladbach',51,11,6,27); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Mülheim an der Ruhr',51,26,6,53); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Oberhausen',51,28,6,52); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Remscheid',51,11,7,12); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Solingen',51,10,7,5); 
     INSERT INTO Rheinland_Staedte 
     VALUES ('Wuppertal',51,16,7,13); 

     create or replace PACKAGE GEOGRAPHICAL_PACKAGE IS 


     FUNCTION DISTANCE(stadt1 VARCHAR2 
         ,stadt2 VARCHAR2) RETURN NUMBER ; 

     END GEOGRAPHICAL_PACKAGE; 
    /
     create or replace PACKAGE BODY GEOGRAPHICAL_PACKAGE IS 

     FUNCTION DISTANCE(stadt1 VARCHAR2 
         ,stadt2 VARCHAR2) RETURN NUMBER IS 
     v_norgr Rheinland_Staedte.Noerdlicher_Grad%TYPE; 
     v_nordmin Rheinland_Staedte.Noerdliche_Minute%TYPE; 
     v_ostgr Rheinland_Staedte.oestlicher_Grad%TYPE; 
     v_ostmin Rheinland_Staedte.oestliche_Minute%TYPE; 
     v_norgr1 Rheinland_Staedte.Noerdlicher_Grad%TYPE; 
     v_nordmin1 Rheinland_Staedte.Noerdliche_Minute%TYPE; 
     v_ostgr1 Rheinland_Staedte.oestlicher_Grad%TYPE; 
     v_ostmin1 Rheinland_Staedte.oestliche_Minute%TYPE; 
     latitude_min NUMBER; 
     longitude_min NUMBER; 
     latitude_min1 NUMBER; 
     longitude_min1 NUMBER; 
     distance NUMBER; 
     BEGIN 
     SELECT Noerdlicher_Grad,Noerdliche_Minute,oestlicher_Grad,oestliche_Minute INTO v_norgr,v_nordmin,v_ostgr,v_ostmin FROM Rheinland_Staedte WHERE STADTNAME=stadt1; 

     SELECT Noerdlicher_Grad,Noerdliche_Minute,oestlicher_Grad,oestliche_Minute INTO v_norgr1,v_nordmin1,v_ostgr1,v_ostmin1 FROM Rheinland_Staedte WHERE STADTNAME=stadt2; 
     latitude_min:=v_norgr+v_nordmin/60; 
     longitude_min:=v_ostgr+v_ostmin/60; 
     latitude_min1:=v_norgr1+v_nordmin1/60; 
     longitude_min1:=v_ostgr1+v_ostmin1/60; 
     distance:= SQRT((latitude_min - latitude_min1)*(latitude_min - latitude_min1) + (longitude_min -longitude_min1)*(longitude_min -longitude_min1)); 
     return distance*60; 
     END; 
     END GEOGRAPHICAL_PACKAGE; 
    /

は、それはあなたが出力を取得したいが、あなたはあなたの関数では、このようなカーソルを返すことができますどのようにdepeneds何両市

+0

あなたの質問を編集し、あなたのテーブルの構造と呼び出しを含めてくださいあなたの関数の署名。ありがとう。 –

+0

なぜあなたはカーソルが必要だと知っていますか?これは[XY問題](http://xyproblem.info/)のように思われます。答えがカーソルであると仮定するのではなく、実際に解決しようとしている問題は何ですか? – MT0

+0

私は緯度と経度を度と分で表した都市名を持っています。私は1つの都市のパラメータでfunktionを書く必要があります。テーブルから他のすべての都市までの距離を返します。それはカーソルの仕事ではありませんか? – Veni

答えて

0

間のリターンの距離私のテーブルと機能です。より良い答えを得るために、より多くの情報を提供する必要があります。

Cursor c1; 
Open c1 for 
select dist_func(city_param,city_id) from table_city ; 
return c1; 
1

使用OracleのSpatialデータ:

Oracleのセットアップ

CREATE TABLE Cities (
    id  NUMBER(8,0), 
    name  VARCHAR2(25), 
    location SDO_GEOMETRY 
); 

INSERT INTO Cities 
      SELECT 1, 'London', SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(-0.1278,51.5074,NULL), NULL, NULL) FROM DUAL 
UNION ALL SELECT 2, 'New York', SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(-74.0059,40.7128,NULL), NULL, NULL) FROM DUAL 
UNION ALL SELECT 3, 'Hong Kong', SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(114.1095,22.3964,NULL), NULL, NULL) FROM DUAL; 

INSERT INTO USER_SDO_GEOM_METADATA (
    TABLE_NAME, COLUMN_NAME, DIMINFO, SRID 
) VALUES (
    'CITIES', 
    'LOCATION', 
    SDO_DIM_ARRAY(
    SDO_DIM_ELEMENT('LONG', -180.0, 180.0, 0.5), 
    SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5) 
), 
    8307 
); 

CREATE INDEX CitiesTable_SIDX ON Cities(location) INDEXTYPE IS MDSYS.SPATIAL_INDEX; 

クエリ

SELECT 
    a.name, 
    b.name, 
    sdo_geom.sdo_distance(a.location, b.location, 0.005, 'unit=mile') distance 
FROM cities a 
    CROSS JOIN 
    cities b 
WHERE a.id < b.id 
ORDER BY distance; 

Outpuトン

NAME      NAME      DISTANCE 
------------------------- ------------------------- ---------- 
London     New York     3470.49915 
London     Hong Kong     5983.3067 
New York     Hong Kong     8057.67161 
0

ここでは、関数である:

CREATE OR REPLACE PACKAGE GEOGRAPHICAL_PACKAGE AS 
    FUNCTION Abstand(v_städteA Rheinlandstädte%rowtype,v_städteB  
    Rheinlandstädte%rowtype) RETURN NUMBER; 
    TYPE ABSTANDSTABELLE IS TABLE OF NUMBER INDEX BY VARCHAR2(30); 
    FUNCTION Entfernung(v_stadt Rheinlandstädte%rowtype) RETURN 
    Abstandstabelle; 

END GEOGRAPHICAL_PACKAGE; 
/
CREATE OR REPLACE PACKAGE BODY GEOGRAPHICAL_PACKAGE AS 

FUNCTION Abstand(v_städteA Rheinlandstädte%rowtype,v_städteB  
Rheinlandstädte%rowtype) 
RETURN NUMBER IS 

abstand NUMBER; 
nordA NUMBER; 
nordB NUMBER; 
ostA NUMBER; 
ostB NUMBER; 

BEGIN 
nordA := v_städteA.MinuteN + v_städteA.GradN*60; 
nordB := v_städteB.Minuten + v_städteB.GradN*60; 
ostA := v_städteA.MinuteO + v_städteA.GradO*60; 
ostB := v_städteB.MinuteO + v_städteB.GradO*60; 

abstand := SQRT((POWER(nordA-nordB, 2)+POWER(ostA-ostB, 2))*1.850); 

RETURN ROUND(abstand,0); 
END Abstand; 


FUNCTION Entfernung(v_stadt Rheinlandstädte%rowtype) 
RETURN Abstandstabelle IS tabelle ABSTANDSTABELLE; 

CURSOR c_städte IS 
SELECT * 
FROM Rheinlandstädte ; 

v_andereStadt Rheinlandstädte%rowtype; 
v_entfernung NUMBER; 

BEGIN 

OPEN c_städte; 

LOOP 

    FETCH c_städte INTO v_andereStadt; 
    v_entfernung := Abstand(v_stadt, v_andereStadt); 
    tabelle(v_andereStadt.stadtname) := v_entfernung; 
    EXIT WHEN c_städte%NOTFOUND; 
END LOOP; 
CLOSE c_städte; 
RETURN tabelle; 
END Entfernung; 

そして、ここではそれを呼び出す方法です:

DECLARE 
v_stadtname_a VARCHAR(20):='Düsseldorf'; 
v_stadtA Rheinlandstädte%rowtype; 
v_stadtB Rheinlandstädte%rowtype; 
abstand NUMBER; 
tabelle GEOGRAPHICAL_PACKAGE.ABSTANDSTABELLE; 
v_stadt Rheinlandstädte%rowtype; 
CURSOR c_sta IS 
    SELECT * FROM Rheinlandstädte; 
BEGIN 

SELECT * INTO v_stadtA 
FROM rheinlandstädte 
WHERE stadtname=v_stadtname_a; 

OPEN c_sta; 
LOOP 
    FETCH c_sta INTO v_stadt; 
    EXIT WHEN c_sta%NOTFOUND; 
    tabelle := GEOGRAPHICAL_PACKAGE.Entfernung(v_stadtA); 
    dbms_output.put_line('Abstand zwischen '||v_stadtA.stadtname||' und '|| 
    v_stadt.stadtname||' beträgt: '||tabelle(v_stadt.stadtname)||' km.'); 
END LOOP; 
CLOSE c_sta; 


END; 
関連する問題