So you are going to build a function that has a MAX # of parameters and then use up to that Max # of parameters? Why exactly are you trying to do this again?
Also, this is NOT really an APEX specific question, I suggest you post it to the SQL and PL/SQL support forum..:SQL and PL/SQL
I have a function called foo, into which I want to pass some indeterminate number of arguments.
I want to build this as a general purpose function that can accept any number of arguments.
PLSQL function does not support which has indeterminate number of arguments .
Before compiling the function you should have a fixed number of Argument .
Mark T. wrote:
I know this must be simple, but I'm apparently not finding the right Google search terms.
I have a function called foo, into which I want to pass some indeterminate number of arguments. Each argument will be the name of a page item.
For example: foo('P21_CUST_NAME','P21_CUST_CITY','P21_CUST_ZIP');
I want to iterate (loop) over the arguments and test the values of each item. Foo will return a string such as .y.n.y. which will then be searched to find any occurrences of .n. If any occurrences of .n. are found, then the page has not been completed fully, and I will show a red icon.
I want to build this as a general purpose function that can accept any number of arguments. The logic within the loop (i.e. null or not) is not at issue here. I can do that without a problem. I just need to know how to loop over every argument passed into foo, whether there is one argument, or three, or twenty-seven.
As stated above, PL/SQL does not support variable parameter lists. These can be approximated using a collection type and its default constructor:
create or replace type t_apex_items is table of varchar2(30); /
create or replace function foo (p_page_items in t_apex_items) return varchar2 is l_foo varchar2(32767); begin for i in 1..p_page_items.count loop l_foo := rtrim(l_foo, '.') || case when v(p_page_items(i)) is null then '.n.' else '.y.' end; end loop; return l_foo; end foo; /
begin dbms_output.put_line(foo(t_apex_items())); dbms_output.put_line(foo(t_apex_items('P21_CUST_NAME'))); dbms_output.put_line(foo(t_apex_items('P21_CUST_NAME','P21_CUST_CITY','P21_CUST_ZIP'))); end; /
While what you are proposing can be achieved using a collection type (or a delimited string and
apex_util.string_to_table), you still have to create these calls wherever you need them, process the results, and create validations to stop page submission and display error messages. It would be a lot simpler—and generally more effective—to use the Value Required setting on the relevant page items and get APEX to handle this automatically.
However, if you must reinvent this yourself, look at using a function like this (reverse the logic and add a filter to the query to include only relevant visible item display types). With this approach only 2 parameters are required, and items will be included automatically rather than having to be hard-coded into function calls.
FAC856, I appreciate the detailed response. Just as a follow up to your "value required" suggestion: Given only the information I provided, your assumption that the values are required for submission was certainly a logical next step, and your suggestion would be perfectly valid. However, the values are not, in fact, required for submission. My very simple example shielded the complexity of a process of 85 steps divided into 8 categories. When one of the 85 steps is completed, it is tagged with a completion date/time by the user, and the field is highlighted in green. Once an entire category of steps is complete, that entire category is "green" (gets a green icon). So it's absolutely permissible for some fields to be null.
var myBigOleListOfArgs = P2_ITEM_1 + '~' + P2_ITEM_2 + '~' + P2_ITEM_3;
var outcome = myLoopyFunction( myBigOleListOfArgs );
Within the function, use the split method to convert the string into an array that you may then loop over:
var myBigOleListOfArgsArray = myBigOleListOfArgs.split('~);
for(var argumentIndex=0; argumentIndex < myBigOleListOfArgsArray.length; argumentIndex++)
// Do Stuff Here...each element is: myBigOleListOfArgsArray[argumentIndex]
It really helps if you provide some context for your questions. With the (little) additional information provided this begins to look like an XY question. Explaining the complete requirements rather than aspects of your proposed solution might result in better overall approaches being suggested.