views:

189

answers:

2

I am currently developing a function that is meant to execute dynamically created SQL statements. This is done by concatenating the columns and fetching them via cursors. The problem is that when there is a function with a comma between its arguments, the concat concatenates the contents of the functions inclusive.

Is it possible to skip contents of every bracket found in a string using REGEXP_SUBTR or REGEXP_REPLACE?

Many thanks in advance for your prompt and kind suggestions.

-- strips out the select list 
src_str := REGEXP_SUBSTR(v_sql, 'SELECT ([[:graph:]]+\ ?){1,1000000}/?');    

-- Replace the commas in the select list with the concat symbol for concatenation 
rep_str := REGEXP_REPLACE(src_str, ', ', p_dot);    

-- Replace the select list with the replace string 
v_query := REPLACE(v_sql, src_str, rep_str); 

v_sql := select a, b, to_char(sysdate, 'dd/mm/yyyy') from demo; 

p_dot := '||'',''||';

currently, it returns:

select a || ',' || b || ',' || to_char(sysdate || ',' || 'dd/mm/yyyy') from demo

but should return something like:

select a || ',' || b || ',' || to_char(sysdate, 'dd/mm/yyyy') from demo

Many thanks Rene, your query worked but I have one more question and here it is

for i in 1 .. p_arglist.count
loop

    -- Search for : in the query
    src_sym := REGEXP_SUBSTR(v_query, ':[[:graph:]]+\ ?', i,i);

    -- Replace the : with each value of p_arglist passed
    v_querymult := REGEXP_REPLACE(v_query, src_sym , p_arglist(i),i,i);

 end loop;
 return v_query;

where p_arglist is a varchar2 varray p_arglist := ('[email protected]','2001')

v_query := 'SELECT A, B, C FROM DEMO WHERE USERID = :USERID AND YEAR = :YEAR';

Currently, it returns

v_query := SELECT A, B, C FROM DEMO WHERE USERID = :USERID AND YEAR = 2001

and skips the first in the list which is the userid. many thanks for your anticipated help

A: 

something like this should do if I understood your requirement correctly:

-- multiple replacements to accomodate for functions with more
-- than two parameters (and accordingly more than one comma)
src_str := regexp_replace(src_str, '(\([^)]+),', '\1##comma-in-function##');
src_str := regexp_replace(src_str, '(\([^)]+),', '\1##comma-in-function##');
src_str := regexp_replace(src_str, '(\([^)]+),', '\1##comma-in-function##');

-- replace the left-over commas
src_str := replace(src_str, ', ', p_dot);

-- turn commas within function call back to commas:
src_str := replace(src_str, '##comma-in-function##', ',');
René Nyffenegger
Many thanks Rene, your query worked but I have one more question. Is it possible to loop through regexp_replace and regexp_subtr functions?I have edited my previous syntax to include it. At the end of the loop it skips the first in the list which is the userid.many thanks for your anticipated help.
Tunde
I have the feeling that you might be better off with using dbms_sql, but that's because I don't really see what you're trying to achieve.
René Nyffenegger
The function is meant to be a general reporting tool that would take report name, version and variables if any of any SQL statement that the report and version requires.all these would be stored in a table that would be retrieved and processed by the function and returned in a string that can be used in all our applications. Yes, I thought of DBMS_SQL but because of the performance issues, it is often advised against. I thought this approach would be easier but from the looks of it; it is not.Many thanks again Rene, would look into DBMS_SQL. Have a wow weekend.
Tunde
A: 

Have you thought about using DBMS_SQL, that should parse the SQL and allow you to bind variables.

See these links for further reading

Oracle Docs

Ask Tom Example

Paul James
Many thanks Paul, I would look into it; thought this approach would be easier but from the looks of things, it is not.
Tunde