Dealing with HTML multi-selects in Oracle's PL/SQL is a bit trickier than I'd like. Depending on how many items the user picks out of the multi-select, you either get back a simple VARCHAR2 object or a special array object. This means you have to write two separate methods to deal with the two cases.
Let's say you've got an HTML form that contains a multi-select like this:
<select multiple name="p_org_id" id="p_org_id" size="3">
<option value="AV001">Amerigo Vespucci & Sons</option>
<option value="AV002">Antarctic Ventures, Inc.</option>
<option value="AV003">Alamo Vectronix Ltd.</option></select>
Let's assume your form is a GET and not a POST. If a user picks one of these items, what gets appended onto the query string will be something like this:
If the user selects a couple of items, the query string will look something like this:
In the first instance, PL/SQL will be looking for a method that handles a VARCHAR2 called p_org_id. I make the p_org_id variable default to null in case the user does not select anything from that multi-select. The spec for this method would be something like this:
procedure process_form(p_org_id VARCHAR2 default null);
In the second instance, you get back a data structure called ident_arr, which is part of the OWA_UTIL package in PL/SQL. One of the nice things here is that you don't have to worry about the null bit; the only way this version of the method would be called is if the user had selected multiple items from your form. The method signature would look something like this:
procedure process_form(p_org_id owa_util.ident_arr);
All that's left is figuring out how to process that data structure. Luckily, it's like the name sounds — just an array you can loop thru.
htp.p('You selected: ');
FOR i IN 1..p_org_id.count LOOP
htp.p('<br/>' || p_org_id(i));END LOOP;
I'm still searching for a way to handle this in a single method but, so far, this is the only way I've found to handle all the possible conditions coming from a multi-select. Two separate methods seems to be the minimum set required. In theory, you could have a third method to handle the null case but, as I did above, I usually combine that with the code handling the VARCHAR2 case.