Search code examples
oracle-databaserestoracle-apexoracle-ords

Multiple values for the same URI parameter


I am creating an API using ORDS (v18.3) via APEX and I need to be able to pass multiple values for the same parameter, eg:

https://server-url/resource?id=1&id=2

This is a third-party requirement which cannot be changed.

When I try using a URL like this only the first parameter is passed, and the second is stripped away.

Is it possible to do what I need using ORDS?


Solution

  • I had a similar problem that I fixed by simply processing the query string.

    Created a function:

    create or replace function array_from_oldschool(p_query_string in varchar2, p_key in varchar2) return apex_t_varchar2 is
      l_ret     apex_t_varchar2 := apex_t_varchar2();
      l_usenext boolean := false;
      l_isval   boolean := false;
      l_arr     apex_t_varchar2;
    begin
      l_arr := apex_string.split(p_query_string, '\s*[=&]\s*');
      for i in 1 .. l_arr.count loop
        if l_usenext = true and l_isval = true then
          l_ret.extend;
          l_ret(l_ret.count) := l_arr(i);
          l_usenext := false;
        end if;
    
        if l_arr(i) = p_key and l_isval = false then
          l_usenext := true;
        end if;
    
        l_isval := not (l_isval);
      end loop;
    
      return l_ret;
    end;
    

    To test: create an ORDS GET service, type PL/SQL

    declare
      l_arr apex_t_varchar2;
    begin
      l_arr := array_from_oldschool(p_query_string => owa_util.get_cgi_env('QUERY_STRING'), p_key => 'id');
    
      for i in 1 .. l_arr.count loop
        htp.prn(l_arr(i) || ' <br>');
      end loop;
    end;
    

    Test it: GET testme/old-school?id=1&id=2&id=10&id=100&id=99

    Output is:

    1
    2
    10
    100
    99
    

    You will need to change a bit of code, going from using owa_util.ident_arr to a TABLE of Varchar2 like apex_T_varchar2. But it should be minimal.

    Regards Olafur

    * EDIT * This function is better since the other one messes up if the query string has empty parameters (i.e. val=&val2=&val4=)

    create or replace function query_string_array(p_key in varchar2) return apex_t_varchar2 is
      l_query_string apex_t_varchar2;
      l_return       apex_t_varchar2 := apex_t_varchar2();
    begin
      l_query_string := apex_string.split(owa_util.get_cgi_env('QUERY_STRING'), '&');
      for i in 1 .. l_query_string.count loop
        if l_query_string(i) like p_key || '=%' then
          if replace(l_query_string(i), p_key || '=', '') is not null then
            l_return.extend;
            l_return(l_return.count) := replace(l_query_string(i), p_key || '=', '');
          end if; --don't add empty/null values
        end if;
      end loop;
      return l_return;
    end;