Oracle查询实现select-from区间逗号替换为||且不影响函数
Oracle SQL字段分隔符替换:将SELECT到首个FROM间的逗号替换为
||(不影响函数内逗号) 需求
自动处理存储在Oracle表中的SQL字符串,将每条SQL语句里第一个SELECT与第一个FROM之间的字段分隔逗号,替换为字符串连接符||,但需保留函数、括号内部的逗号不被修改。
原示例(AS IS)
with result as (select column_a, column_b, count(*) from (select column1, column2, column3 .. select column1, count(distinct coalesce(column2, cast('zz' as nvarchar2(2)))) as value from ... select count(*) from (select ....
期望结果(EXPECTED)
with result as (select column_a || column_b || count(*) from (select column1, column2, column3 .. select column1 || count(distinct coalesce(column2, cast('zz' as nvarchar2(2)))) as value from ... select count(*) from (select column1, column2, column3 ..
解决方案
利用Oracle的REGEXP_REPLACE函数实现嵌套正则匹配,精准定位目标范围并替换指定逗号:
假设存储SQL语句的表为sql_queries,存储SQL文本的字段为sql_text,执行以下查询即可得到转换后的SQL:
SELECT REGEXP_REPLACE( sql_text, '(SELECT\s+)(.*?)(\s+FROM)', '\1' || REGEXP_REPLACE('\2', ',(?![^()]*\))', ' || ') || '\3', 1, 1, 'i' ) AS transformed_sql FROM sql_queries;
正则逻辑说明
外层正则:
(SELECT\s+)(.*?)(\s+FROM)- 捕获第一个
SELECT关键字(含后续空格)、SELECT到首个FROM之间的所有内容、首个FROM关键字(含前置空格) - 参数
1,1表示只匹配第一条符合规则的SELECT-FROM片段,'i'表示不区分大小写,兼容select/from小写写法
- 捕获第一个
内层正则:
,(?![^()]*\))- 匹配不在括号内部的逗号:通过正向否定断言
(?![^()]*\))确保逗号后面不会先出现右括号(即该逗号不在任何函数或括号块内) - 将匹配到的逗号替换为字符串连接符
||
- 匹配不在括号内部的逗号:通过正向否定断言
注意事项
- 该方案仅处理每条SQL语句中第一个
SELECT与第一个FROM之间的内容,嵌套在子查询中的SELECT-FROM不会被修改,完全匹配需求示例 - 若SQL语句中存在注释、特殊字符嵌套等复杂场景,可能需要微调正则规则适配具体情况
内容的提问来源于stack exchange,提问作者Mathew Linton
相关产品推荐
相关产品推荐

