Search code examples
oracle-databaseplsqloracle-sqldeveloperoracle-spatial

SQLDeveloper : Not enough arguments


I'm writing an APEX application which utilises spatial for proximity searching via Googlemaps API, I've built the function and it compiles fine, however whenever I try to run it in SQLDeveloper I get the error not enough arguments.

The function I created to set the new lat/long point takes one input of postcode from my stores table, it then uses the Google map API to return the long lat co-ords for that postcode, which on return builds an SDO_GEOMETRY object, which is returned and set in a location column in the stores table.

Function code:

CREATE OR REPLACE FUNCTION set_spatial_point
( 
    -- Only accept postcodes from the store table
    p_postcode stores.postcode%TYPE
)
    RETURN MDSYS.SDO_GEOMETRY
IS
    -- Build local variables
    l_lng      VARCHAR2(100);
    l_lat      VARCHAR2(100);
    n_spatial_object MDSYS.SDO_GEOMETRY;
BEGIN
    -- Populate long and lat parameters
    POSTCODE_TO_LAT_LNG_GM_API(p_postcode, l_lat, l_lng);

    -- Populate the new spatial object
    n_spatial_object := MDSYS.SDO_GEOMETRY
    (
        -- use 01 as we wish to add the point to the map
        2001, 
        -- SRID for WGS84 longitutde/latitude format
        8307,
         -- Set the information of the point ( we don't need a Z co-ord )
        SDO_POINT_TYPE
        (
            l_lng,
            l_lat,
            null
         ),
        null,   -- We have no SDO_ELEM_INFO_ARRAY
        null    -- We have no SDO_ORDINATE_ARRAY
    );

    -- Return the new spatial object
    dbms_output.put_line('sdo_gtype='||n_spatial_object.sdo_gtype);
    dbms_output.put_line('first element from sdo_ordinates='||n_spatial_object.sdo_ordinates(1));
    RETURN n_spatial_object;
END set_spatial_point;

Why am I getting the not enough arguments error, even when I call it with a valid stores.postcode%TYPE, ( I have tried changing to VARCHAR2 but that doesn't make any difference.)

EDIT: After creating the function, I run a call to the method:

DECLARE
   my_object    MDSYS.SDO_GEOMETRY;  
BEGIN
  my_object := set_spatial_value('MK80PB');
END;

I now get the following error:

Error starting at line : 1 in command -
DECLARE
  my_object    MDSYS.SDO_GEOMETRY;  
BEGIN
my_object := set_spatial_value('MK80PB');
END;
Error report -
ORA-06550: line 4, column 14:
PLS-00201: identifier 'SET_SPATIAL_VALUE' must be declared
ORA-06550: line 4, column 1:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

Solution

  • The error you get is obvious: you create the function as SET_SPATIAL_POINT() but you call SET_SPATIAL_VALUE() and that obviously fails since it does not exist.

    Now, let's try this out. I had to replace some of your code since I don't have your declarations of the STORES table or the Google call, so I hard-coded the results from that call:

    CREATE OR REPLACE FUNCTION set_spatial_point
    ( 
        -- Only accept postcodes from the store table
        p_postcode varchar2
    )
        RETURN SDO_GEOMETRY
    IS
        -- Build local variables
        l_lng      VARCHAR2(100);
        l_lat      VARCHAR2(100);
        n_spatial_object SDO_GEOMETRY;
    BEGIN
        -- Populate long and lat parameters
        -- POSTCODE_TO_LAT_LNG_GM_API(p_postcode, l_lat, l_lng);
        l_lat:=45.3;
        l_lng:= 3.7;
    
        -- Populate the new spatial object
        n_spatial_object := SDO_GEOMETRY
        (
            -- use 01 as we wish to add the point to the map
            2001, 
            -- SRID for WGS84 longitutde/latitude format
            8307,
             -- Set the information of the point ( we don't need a Z co-ord )
            SDO_POINT_TYPE
            (
                l_lng,
                l_lat,
                null
             ),
            null,   -- We have no SDO_ELEM_INFO_ARRAY
            null    -- We have no SDO_ORDINATE_ARRAY
        );
    
        -- Return the new spatial object
        dbms_output.put_line('sdo_gtype='||n_spatial_object.sdo_gtype);
        dbms_output.put_line('first element from sdo_ordinates='||n_spatial_object.sdo_ordinates(1));
        RETURN n_spatial_object;
    END set_spatial_point;
    /
    show errors
    

    That works fine.

    Let's try it out:

    SQL> select set_spatial_point('XXXX') from dual;
    ERROR at line 1:
    ORA-06531: Reference to uninitialized collection
    ORA-06512: at "SCOTT.SET_SPATIAL_POINT", line 38
    

    Again, this is obvious. The error is on line 38:

            dbms_output.put_line('first element from sdo_ordinates='||n_spatial_object.sdo_ordinates(1));
    

    That fails (obviously again) since n_spatial_object.sdo_ordinates() is null (like you wrote on line 32.

    Let's remove those debugging lines and redefine the function. Then let's try it out. It now works as expected:

    SQL> select set_spatial_point('XXXX') from dual;
    
    SET_SPATIAL_POINT('XXXX')(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INF
    -------------------------------------------------------------------------------
    SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(3.7, 45.3, NULL), NULL, NULL)
    
    1 row selected.