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

Why cursor doesn't reflect actual query data?

我遇到了需要使用 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个) 作为距离的最后一列,为什么我不能在光标内获得结果,但如果我做一个简单的 select 就可以? 非常感谢任何帮助! 提前致谢!

首先看起来有问题的是你在哪里做的:

SDO_POINT_TYPE(longitud, latitud, null)

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

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

在变量名前加上过程名使它们成为 qualified identifiers:

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

或更改名称以免冲突。通常使用前缀来使名称 from/defined 的位置以及它们的范围更清楚,例如p_longitud 用于正式过程参数。