【问题标题】:Execute SQL Script file with Select query and Dynamic SQL使用 Select 查询和动态 SQL 执行 SQL 脚本文件
【发布时间】:2018-01-20 19:51:03
【问题描述】:

我需要执行许多带有动态 sql 查询的 sql 文件,如下所示

Query1.sql

set @a= (select col_value1 from table1 where x=y);    
set @b= (select col_value2 from table2 where x1=@a);

prepare script from @b;
execute script;
deallocate prepare script;

我需要在执行后获取 ResultSet 对象以进行进一步处理。

我尝试过使用 iBatis 框架中的 ScriptRunner。在那里我们可以执行查询,但无法获取 ResultSet 对象。

此外,还看到了一些通过 RunTime 作为系统命令执行的方法。由于环境是基于线程的,我不推荐使用这种方法。

有没有其他方法可以做到这一点。 ?

提前致谢。

【问题讨论】:

  • 用您正在使用的数据库标记您的问题。

标签: java mysql sql jdbc


【解决方案1】:

也许只是用正则表达式解析你的文件,然后用替换的参数调用查询?我想出了这样的事情:

package com.company;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

private static String queryFile() {
    return "set @a= (select col_value1 from table1 where x=y);\n" +
            "set @b= (select col_value2 from table2 where x1=@a);\n" +
            "prepare script from @b;\n" +
            "execute script;\n" +
            "deallocate prepare script;";
}

private static final Pattern QUERY_PATTERN = Pattern.compile("set (@.)= (.*.)");
private static final Pattern QUERY_VARIABLE_MATCHER = Pattern.compile("@.");

public static void main(String[] args) {
    Map<String, String> queryMap = new LinkedHashMap<String, String>();
    String lines[] = queryFile().split("\n");
    for (String line : lines) {
        Matcher matcher = QUERY_PATTERN.matcher(line);
        if (matcher.matches()) {
            String key = matcher.group(1);
            String query = matcher.group(2);
            queryMap.put(key, query);
        }
    }

    invokeQueries(queryMap);
}

/**
 * Invokes queries parsed from a file. Works only if queries are sorted properly (query B uses a query A result).
 */
private static void invokeQueries(Map<String, String> queryMap) {
    Map<String, String> queryResults = new HashMap<String, String>();
    for (Map.Entry<String, String> entry : queryMap.entrySet()) {
        String query = entry.getValue();
        Matcher matcher = QUERY_VARIABLE_MATCHER.matcher(query);
        if (!matcher.find()) {
            String queryResult = mockInvokeQuery(query);
            queryResults.put(entry.getKey(), queryResult);
            System.out.println("Invoked query: " + query + " with result : " + queryResult);
        } else {
            matcher.reset();
            System.out.println("Replacing query parameters for query: " + query);
            while (matcher.find()) {
                String variable = matcher.group();
                String replacedQuery = query.replaceAll(variable, queryResults.get(variable));
                String queryResult = mockInvokeQuery(query);
                queryResults.put(entry.getKey(), queryResult);
                System.out.println("Invoked query with replaced parameters:: " + replacedQuery + " with result: " + queryResult);
            }
        }
    }
}

/**
 * Invoke your query and get your result set
 */
private static String mockInvokeQuery(String query) {
    return String.valueOf(query.hashCode());
}

/**
 * Replaces @ parameter for all queries within a hashmap. It won't work properly if queries are dependent on each other.
 */
private static Map<String, String> replaceQueryVariables(Map<String, String> queryMap) {
    Map<String, String> replacedQueries = new HashMap<String, String>();
    for (Map.Entry<String, String> entry : queryMap.entrySet()) {
        String query = entry.getValue();
        Matcher matcher = QUERY_VARIABLE_MATCHER.matcher(query);
        while (matcher.find()) {
            String variable = matcher.group();
            String replacedQuery = query.replaceAll(variable, queryMap.get(variable));
            replacedQueries.put(entry.getKey(), replacedQuery);

        }
    }
    return replacedQueries;
}

}

结果是:

Invoked query: (select col_value1 from table1 where x=y); with result : -316456543
Replacing query parameters for query: (select col_value2 from table2 where x1=@a);
Invoked query with replaced parameters:: (select col_value2 from table2 where x1=-316456543); with result: -1396099308

【讨论】:

  • 谢谢米哈尔。这很有帮助。
  • 我的要求略有不同。第二个“集合”包含一个 concat(),即 set @b = concat(.... (select a from b where c =@a) ....)。如果我们分开执行,第二条语句会报错。
猜你喜欢
  • 2021-07-17
  • 2017-01-07
  • 2013-01-06
  • 1970-01-01
  • 2020-06-24
  • 1970-01-01
  • 1970-01-01
  • 2015-02-07
  • 2019-02-25
相关资源
最近更新 更多