为什么游标不能反映实际的查询数据?

时间:2018-06-09 14:10:25

标签: oracle plsql oracle-spatial

我遇到了我需要用oracle执行的查询,而且我得到了疯狂的数据。这是我的存储过程:

CREATE OR REPLACE PROCEDURE GET_FARMACIAS_GEOLOCALIZACION(p_recordset OUT SYS_REFCURSOR, plan PLANES_SQL.PLAN_%TYPE, LATITUD NUMBER, LONGITUD NUMBER)
IS

BEGIN
   p_recordset := NULL;
   OPEN p_recordset FOR
    SELECT * FROM(
        SELECT DOMICILIOS_WEB_APP.DOMICILIO, DOMICILIOS_WEB_APP.LOCALIDAD, DOMICILIOS_WEB_APP.LATITUD, DOMICILIOS_WEB_APP.LONGITUD, 
                CARTILLA.NOMBRE + ' ' + CARTILLA.APELLIDO AS NOMBRE, DOMICILIOS_WEB_APP.CP, DOMICILIOS_WEB_APP.PROVINCIA,
                SDO_GEOM.SDO_DISTANCE(SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(longitud, latitud, null), null, null),
                                    SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(DOMICILIOS_WEB_APP.LONGITUD, DOMICILIOS_WEB_APP.LATITUD, null), null, null),
                                    0.0001,
                                    'unit=M'
                                    ) AS DISTANCIA 
        FROM DOMICILIOS_WEB_APP
        JOIN ESPCAR ON ESPCAR.IDCARTILLA = DOMICILIOS_WEB_APP.IDCARTILLA
        JOIN CARTILLA ON ESPCAR.IDCARTILLA = CARTILLA.IDCARTILLA
        WHERE ESPCAR.IDESPECIALIDAD = 900
        AND DOMICILIOS_WEB_APP.LATITUD IS NOT NULL
        AND DOMICILIOS_WEB_APP.LONGITUD IS NOT NULL
        ORDER BY DISTANCIA)
    WHERE ROWNUM <= 50;
END GET_FARMACIAS_GEOLOCALIZACION;
/

创建后,我运行一个简单的查询来检查结果,我做了:

DECLARE
    domicilio DOMICILIOS_WEB_APP.DOMICILIO%TYPE;
    localidad DOMICILIOS_WEB_APP.LOCALIDAD%TYPE;
    latitud_res DOMICILIOS_WEB_APP.LATITUD%TYPE;
    longitud_res DOMICILIOS_WEB_APP.LONGITUD%TYPE;
    nombre CARTILLA.NOMBRE%TYPE;
    cp DOMICILIOS_WEB_APP.CP%TYPE;
    provincia DOMICILIOS_WEB_APP.PROVINCIA%TYPE;
    distancia NUMBER;
    farmacias_ref_cursor_2   SYS_REFCURSOR;
BEGIN
    DBMS_OUTPUT.PUT_LINE('Pruebas Farmacias por Geolocalización');
    USRMDF.GET_FARMACIAS_GEOLOCALIZACION(farmacias_ref_cursor_2,'PLATINO', -34.588769800, -58.430460400);
    LOOP
        FETCH farmacias_ref_cursor_2 INTO domicilio, localidad, latitud_res, longitud_res, nombre, cp, provincia, distancia;
        EXIT WHEN farmacias_ref_cursor_2%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(domicilio || '     ' || localidad || '     ' || latitud_res || '     ' || longitud_res || '     ' || nombre || '     ' || cp || '     ' || provincia || '     ' || distancia);
    END LOOP;
    CLOSE farmacias_ref_cursor_2;
END;

但是我得到了奇怪的结果,你可以看到下一个:

Pruebas Farmacias por Geolocalización
H. YRIGOYEN 5397            -34.717136     -58.393707          1826          0
CALLE 12 ESQ. 48 S/N            -34.92125     -57.954334          1900          0
CALLE 7 ESQ. 520 BIS 1160            -34.890873     -57.981945          1900          0
CALLE 16 344            -34.906075     -57.982067          1900          0
AV. ANDRES ROLON 1799            -34.46889     -58.541298          1643          0
25 DE MAYO 504            -34.61381     -58.952984          1748          0
AV. MONTEVIDEO 302            -34.865932     -57.88902          1923          0
PTE. JUAN D. PERON 485            -34.366524     -58.75049          1625          0
MAIPU 1369            -34.388844     -58.738483          1625          0
SUIPACHA 1110            -34.094833     -59.029533          2800          0
COLECTORA ESTE Y 117 KM 55            -34.378002     -58.75401          1625          0
CALLE 13 1118            -34.875633     -58.050636          1896          0
CALLE 116 251            -34.897297     -57.955044          1900          0
AV. 60 1979            -34.947067     -57.970398          1900          0
MARINERO PANNO 480            -33.504807     -60.060574          2914          0
FLORIDA 52            -34.60746     -58.37501          9999          0
SALADILLO 2016            -34.661446     -58.51675          9999          0
AV. 25 145            -34.919914     -57.98412          1900          0
AV. RIVADAVIA 4178            -34.613094     -58.42463          9999          0
AV. 7 ESQ. 67 1701            -34.926846     -57.933594          1900          0
DE LA TORRE 1501            -34.09591     -59.03378          2800          0
LIMA 267            -34.611576     -58.381844          9999          0
CALLE 467 1294            -34.876186     -58.053932          1896          0
EVA PERON 2399            -34.68148     -58.672752          1716          0
BUSTAMANTE 821            -34.690113     -58.37913          1824          0
CALLE 2 1/2 190            -34.89584     -57.96372          1900          0
BOULEVARD BUENOS AIRES 1024            -34.812576     -58.453156          1838          0
LAVALLE 295            -34.09985     -59.026917          2800          0
LEBENSOHN 11            -34.713097     -58.267982          1876          0
CALLE 12 ESQ. 55 1100            -34.92125     -57.954334          1900          0
JEREZ 502            -34.866276     -57.903214          1925          0
SARMIENTO 298            -34.660786     -58.361412          1824          0
MAXIMO PAZ 1084            -34.69151     -58.40009          1824          0
RUCCI 1253            -34.79921     -58.337395          1849          0
ENRIQUE PEREZ SIMON 4510            -34.772778     -58.645622          1759          0
PTE. JUAN DOMINGO PERON 1284            -34.544792     -58.708546          1663          0
JOLI 1311            -34.65714     -58.771114          1742          0
AV. ROLON 1820            -34.47083     -58.52861          1609          0
IGNACIO RUCCI 2238            -34.691376     -58.592896          1765          0
MUÑIZ 3372            -34.56666     -59.21667          6712          0
AV. COSTANERA Y R. OBLIGADO S/N            -34.572212     -58.3931          9999          0
AV. SAENZ PEÑA 910            -34.60477     -58.379684          9999          0
ESTADOS UNIDOS 4111           -31.4235191     -64.1336517          5000          0
GARIBALDI 3 74          -33.3294861     -60.2120048          2900          0
TUCUMAN 623 ESQ . LOS PINOS          -31.6518021     -63.9123955          5960          0
AVENIDA GUEMES 203          -26.0749747     -65.9757262          4427          0
BRANDSEN 4 08          -35.0596979     -58.7572859          1814          0
LIBERTAD 598          -35.0550416     -58.759832          1814          0
SAAVEDRA 469          -38.720112     -62.392629          8105          0
ALBERDI ESQ SARMIENTO          -27.75     -57.6166667          3407          0

正如您所看到的那样,最后一列的“Distancia”始终为0,但如果我在存储过程中运行相同的查询而不使用存储过程,则如下所示:

SELECT * FROM(
    SELECT DOMICILIOS_WEB_APP.DOMICILIO, DOMICILIOS_WEB_APP.LOCALIDAD, DOMICILIOS_WEB_APP.LATITUD, DOMICILIOS_WEB_APP.LONGITUD, 
            CARTILLA.NOMBRE + ' ' + CARTILLA.APELLIDO AS NOMBRE, DOMICILIOS_WEB_APP.CP, DOMICILIOS_WEB_APP.PROVINCIA,
            SDO_GEOM.SDO_DISTANCE(SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(-58.430460400, -34.588769800, null), null, null),
                                SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(DOMICILIOS_WEB_APP.LONGITUD, DOMICILIOS_WEB_APP.LATITUD, null), null, null),
                                0.0001,
                                'unit=M'
                                ) AS DISTANCIA 
    FROM DOMICILIOS_WEB_APP
    JOIN ESPCAR ON ESPCAR.IDCARTILLA = DOMICILIOS_WEB_APP.IDCARTILLA
    JOIN CARTILLA ON ESPCAR.IDCARTILLA = CARTILLA.IDCARTILLA
    WHERE ESPCAR.IDESPECIALIDAD = 900
    AND DOMICILIOS_WEB_APP.LATITUD IS NOT NULL
    AND DOMICILIOS_WEB_APP.LONGITUD IS NOT NULL
    ORDER BY DISTANCIA)
WHERE ROWNUM <= 50;

我得到了我想要的结果!

JOSE. A CABRERA 5000        -34,590034  -58,432186      9999        211,493889772118
AV. CORDOBA 4601        -34,594273  -58,430042      9999        611,692597266816
AV. RAUL SCALABRINI ORTIZ 868       -34,595932  -58,43265       9999        819,523932197982
HONDURAS 3953       -34,5941    -58,418957      9999        1209,67973943129
AV. SANTA FE 3944       -34,58309   -58,41907       9999        1220,27184702758
AV. CORDOBA 3949        -34,59771   -58,422543      9999        1229,2853443306
AV. SANTA FE 4800       -34,577927  -58,427406      9999        1235,0376542743
AV. CORDOBA 5901        -34,585377  -58,44349       9999        1253,24408513258
AV. CORDOBA 3902        -34,597755  -58,421795      9999        1274,93439078794
AV. SANTA FE 5100       -34,576675  -58,431564      9999        1345,52713284701
INDEPENDENCIA 7032          -34,58  -58,41971       1669        1385,38266709098
RUTA PANAM. RAMAL PILAR KM 42.5 PARK OFFICE NORTE       -34,58  -58,41971       1669        1385,38266709098
SCALABRINI ORTIZ 328        -34,599678  -58,43848       9999        1416,16966524245
AV. CORRIENTES 5288         -34,599106  -58,43965       9999        1423,18135155578
AV. CORRIENTES 4647         -34,60213   -58,43101       9999        1482,94685972992
ARENALES 3810       -34,584515  -58,415096      9999        1486,5286778011
REPUBLICA DOMINICANA 3358       -34,591145  -58,41341       9999        1586,2610857951
GUEMES 3500         -34,589382  -58,41277       9999        1624,37628749551
AV. SANTA FE 3380       -34,58725   -58,41282       9999        1627,14760562725
AV. CERVIÑO 4716        -34,57501   -58,423737      9999        1646,35191268326
AV. SANTA FE 3350       -34,587536  -58,412346      9999        1667,49968515136
TUCUMAN 850         -34,603935  -58,432304      1661        1690,803564733
AV. CABILDO 100         -34,574207  -58,437263      9999        1731,87025451283
AV. CORDOBA 3381        -34,597904  -58,41435       9999        1791,93147327723
AV. RAUL SCALABRINI ORTIZ 14        -34,60208   -58,44243       9999        1840,06983367351
GUEMES 3200         -34,59104   -58,410492      9999        1849,15607406273
GUEMES 3200         -34,59104   -58,410492      9999        1849,15607406273

(我刚刚复制了一些,而不是全部50个) 作为距离的最后一列,为什么我不能在光标内得到结果但是如果我做一个简单的选择我可以吗? 任何帮助真的很感激! 提前谢谢!

1 个答案:

答案 0 :(得分:4)

看起来像问题的第一件事就是你这样做:

SDO_POINT_TYPE(longitud, latitud, null)

您假设这些参数是过程参数,即被视为escaped identifiers;但名称解析规则意味着它们实际上是表值,因为表列名称优先于PL / SQL标识符。

所以你实际上并没有使用传入的值。对SDO_POINT_TYPE的两次调用都使用相同的表值;因此距离总是为零。

使用过程名称作为变量名称的前缀,使其成为qualified identifiers

SDO_POINT_TYPE(GET_FARMACIAS_GEOLOCALIZACION.longitud, GET_FARMACIAS_GEOLOCALIZACION.latitud, null)

或更改名称,以免它们发生冲突。通常使用前缀来使名称来自/定义的位置更清楚,以及它们的范围是什么,例如: p_longitud用于正式的程序论证。