2010-03-18 121 views
1

我目前正在开发一个旨在执行动态创建的SQL语句的函数。这是通过连接列并通过光标获取它们来完成的。问题是当函数的参数之间有一个逗号时,concat会连接函数的内容。在Oracle 10G中搜索并替换字符串中的括号

是否可以使用REGEXP_SUBTR或REGEXP_REPLACE跳过字符串中找到的每个括号的内容?

非常感谢您的迅速和善意的建议。

-- 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 := '||'',''||'; 

目前,它返回:

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

但应该返回类似:

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

非常感谢刘若英,您的查询工作,但我有一个问题,就是这样

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; 

其中p_arglist是一个VARCHAR2 VARRAY p_arglist:=( '[email protected]', '2001')

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

目前,它返回

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

并且跳过在其列表中的第一用户标识。 非常感谢您的预期帮助,如果我理解正确的您的要求

+1

帖子你这么远的东西。 – 2010-03-18 14:33:29

+0

请参阅上面编辑的问题。谢谢 – Tunde 2010-03-18 14:38:02

+0

你能否提供你的'v_sql',目前的结果和期望的结果呢? – 2010-03-18 14:41:00

回答

0

你有没有想过使用DBMS_SQL,应分析SQL,并允许您绑定变量。

看到这些链接进一步阅读

Oracle Docs

Ask Tom Example

+0

非常感谢保罗,我会研究它;认为这种方法会更容易,但从外观看,事实并非如此。 – Tunde 2010-03-19 09:30:25

0

这样的事情应该做的:

-- 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##', ','); 
+0

非常感谢Rene,你的查询很有用,但我还有一个问题。是否有可能循环regexp_replace和regexp_subtr函数? 我编辑了我以前的语法来包含它。在循环结束时,它跳过列表中的第一个用户标识。 非常感谢您的期望帮助。 – Tunde 2010-03-18 16:58:00

+0

我觉得使用dbms_sql可能会更好,但那是因为我没有真正看到你想要实现的目标。 – 2010-03-18 21:44:26

+0

该函数旨在成为一个通用的报表工具,如果报表和版本需要任何SQL语句,该函数将取得报表名称,版本和变量。 所有这些将被存储在一个表中,该表将被该函数检索和处理,并返回一个可用于我们所有应用程序的字符串。是的,我想到了DBMS_SQL,但由于性能问题,通常不建议。我认为这种方法会更容易,但从外观上看,不是这样。 非常感谢Rene,会考虑DBMS_SQL。祝你周末愉快。 – Tunde 2010-03-19 09:29:10