首页 > 解决方案 > 使用java中的正则表达式剥离或概括SQL字符串中的所有函数调用参数

问题描述

我有许多 sqls 调用将打印在记录器中,这些调用具有表值函数调用,我们希望对其进行概括,以便我们可以在 splunk 中获得更好的计数和统计信息。

我们在地图中有以下类型的 sql 将打印在日志中


select * from dbo.function1(param1, (param2), '121,3232,424', (param4) ) join dbo.functions2(param1, param2);
select * from dbo.function1(param1) join function2('demo','12134,4343,4343')

可能有带有“,”或没有“,”的连接或不连接的sql,并且可能存在带有内部查询的查询,如下所示:-

select col1, col2 from table1, (select col1, col2 from funct1(param1, param2) a join table2 b on a.id=b.id ) table2;

我们想将其概括为如下所示:-

select * from dbo.function1(stripped) join dbo.functions2(stripped);
select * from dbo.function1(stripped) join function2(stripped)
select col1, col2 from table1, (select col1, col2 from funct1(stripped) a join table2 b on a.id=b.id ) table2;

这样我们也可以使用 diff 参数获取 sql 的计数。挑战是两个括号,要么是贪婪,要么是直到第一个右括号。截至目前,我们制作的正则表达式如下所示

"[ ][_0-9a-z]{0,30}[.]?[_0-9a-z]{5,128}([(].*?[)])"

这个正则表达式将打印匹配,直到dbo.function1(param1, (param2)这个函数调用的最后一个括号。还需要处理内置函数,通过给出 5 的长度来处理以避免函数 max()、min 但仍然有 COALESCE() 等函数。

标签: javaregex

解决方案


这可能会有所帮助:

input.replaceAll("(select \\* from [^\\(]+).*?( join [^\\(]+)[^;]+, "$1(stripped)$2(stripped)");

试验台:

public static void main(String[] args) {
    String input = "select * from dbo.function1(param1, (param2), '121,3232,424', "
            + "(param4) ) join dbo.functions2(param1, param2);\n\n"
            + "select * from dbo.function1(param1) join function2('demo','12134,4343,4343')\n";

    String result =
            input.replaceAll("(select \\* from [^\\(]+).*?( join [^\\(]+)[^;]+"
                    , "$1(stripped)$2(stripped)");

    System.out.println(result);
}

输出:

select * from dbo.function1(stripped) join dbo.functions2(stripped);

select * from dbo.function1(stripped) join function2(stripped)

推荐阅读