我想从SQL查询中获取所有参数。在这种情况下,查询是数组中的纯字符串。 我有很多成对的查询,格式如下:
SELECT * FROM my_table t WHERE (t.attr1 = ? AND t.attr2 = ?) OR t.attr3= ?
其对是(其中包含我要检索的参数):
SELECT * FROM my_table t WHERE (t.attr1 = 3 AND t.attr2 = 'str') OR t.attr3= 4
所以输出将是:
3, 'str' and 4.
如何基于此对检索这些值?
我在Java中尝试使用正则表达式,但是会很困难,因为?可以是数字 字符串等等。该字符串可以包含另一个?这是字符串的一部分,例如:
UPDATE my_table SET attr2 = ? WHERE attr5 = ?
UPDATE my_table SET attr2 = 'Is it true?' WHERE attr5 = 'What is it?'
答案 0 :(得分:1)
这是一个使用基本Java regex模式匹配的工作脚本。它通过执行两次比赛来工作。首先,它查找分配给?
位置占位符的每列/别名。然后,对于每个匹配的列/别名,它将对具有绑定值的查询字符串进行第二次查找。
String query1 = "SELECT * FROM my_table t WHERE (t.attr1 = ? AND t.attr2 = ?) OR t.attr3= ?";
String query2 = "SELECT * FROM my_table t WHERE (t.attr1 = 3 AND t.attr2 = 'str') OR t.attr3= 4";
String p1 = "([\\w.]+)\\s*=\\s*\\?(?=(([^']*'){2})*[^']*$)";
Pattern r1 = Pattern.compile(p1);
Matcher m1 = r1.matcher(query1);
// for each matching column/alias with a placeholder
while (m1.find()) {
String p2 = m1.group(1) + "\\s*=\\s*([\\w.']+)";
Pattern r2 = Pattern.compile(p2);
Matcher m2 = r2.matcher(query2);
// if we find it in the second query string, then print the value
if (m2.find()) {
System.out.println("Column: " + m1.group(1) + " has parameter value: " + m2.group(1));
}
}
Column: t.attr1 has parameter value: 3
Column: t.attr2 has parameter value: 'str'
Column: t.attr3 has parameter value: 4
请注意,我在这里做一些假设,包括匹配的列将只包含单词字符(\w
)和点,并且匹配的值将仅包含单词字符和单引号(对于字符串文字)。上面的代码可能会在很多情况下失败,这还取决于您的数据库及其特定语法。我正在为您提出的问题提供立即的解决方案,并作为一种可行的通用方法。
答案 1 :(得分:1)
您可以使用此方法来执行此操作,即在查询中将每个?
替换为(.*)
,然后根据它创建一个模式。然后应用另一对具有实际值的字符串,然后打印出将根据查询字符串中存在的?
动态创建的所有组中的值。
这是同样的Java代码。
// This map stores your paired queries where key stores the placeholder query and value stores the query having actual parameters.
Map<String, String> pairMap = new HashMap<>();
pairMap.put("SELECT * FROM my_table t WHERE (t.attr1 = ? AND t.attr2 = ?) OR t.attr3= ?", "SELECT * FROM my_table t WHERE (t.attr1 = 3 AND t.attr2 = 'str') OR t.attr3= 4");
pairMap.put("UPDATE my_table SET attr2 = ? WHERE attr5 = ?", "UPDATE my_table SET attr2 = 'Is it true?' WHERE attr5 = 'What is it?'");
pairMap.forEach((k,v) -> {
System.out.println("For query: "+k);
k = k.replaceAll("([*+^$()\\[\\]{}])", "\\\\$1"); // this escapes all the characters that have special meaning in regex so they get treated as literal characters
k = k.replaceAll("\\?", "(.*)");
Pattern p = Pattern.compile(k);
Matcher m = p.matcher(v);
if (m.matches()) {
for (int i=0;i<m.groupCount();i++) {
System.out.println(m.group(i+1));
}
} else {
System.out.println("Didn't match");
}
System.out.println();
});
哪些印刷品
For query: SELECT * FROM my_table t WHERE (t.attr1 = ? AND t.attr2 = ?) OR t.attr3= ?
3
'str'
4
For query: UPDATE my_table SET attr2 = ? WHERE attr5 = ?
'Is it true?'
'What is it?'
如您所见,该代码适用于查询字符串中占位符?
的任何变量值,并打印配对查询中存在的所有具有实际值的值。