PLSQL正则提取user_source中跨多行的raise_application_error完整调用
问题原因
原查询无法拿到完整调用的核心原因有两点:
- Oracle正则默认
.通配符不匹配换行符,你传入的'm'模式参数仅能让^、$匹配每行的首尾位置,不会改变.的匹配规则,因此第一行换行后的内容不会被默认的.*捕获。 - 手动拼接单个
CHR(10)加.*的写法仅能适配刚好跨2行的调用场景,若函数调用跨3行及以上(比如错误消息也做了换行拼接),该写法会直接失效,通用性极差。
正确查询语句
使用支持跨行匹配的正则参数+非贪婪匹配规则即可拿到完整调用,代码如下:
SELECT t.name, TRIM(regexp_substr( t.TEXT, 'raise_application_error\(.*?\);', 1, 1, 'n' )) AS text FROM user_source t WHERE t.TEXT LIKE '%raise_application_error%';
写法说明
- 正则中
\(、\)是对括号做转义:括号在正则语法中属于分组特殊字符,要匹配代码里的实际括号必须加转义符。 - 传入
'n'作为正则匹配参数:该参数是Oracle正则专属的跨行匹配开关,开启后.通配符可以匹配包括换行符在内的任意字符,不需要手动拼接CHR(10)、CHR(13)这类换行符,Windows、Unix格式的换行都能兼容。 .*?是非贪婪匹配逻辑:会从raise_application_error(开始,尽可能短的匹配内容,碰到第一个);(即函数调用的结束标识)就停止匹配,不会把后续无关的代码行带进来。- 外层嵌套
TRIM()函数:用于清除匹配结果前后多余的缩进空格、首尾换行,最终得到格式干净的完整调用语句。
针对你给出的测试代码片段,上述查询返回的TEXT字段内容就是你期望的raise_application_error(-20100, 'Explanation message.');,不会出现仅返回第一行内容的问题。
内容的提问来源于stack exchange,提问作者mertcan
相关产品推荐
相关产品推荐

