2017-08-12 96 views
0

我有执行动态SQL许多SQL文件的要求提交查询类似下列执行SQL脚本Select查询和动态SQL

QUERY1.SQL

set @a= (select col_value1 from table1 where x=y);  
set @b= (select col_value2 from table2 where [email protected]); 

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

我需要得到ResultSet对象执行后进行进一步处理。

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

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

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

在此先感谢。

+0

标签您与您正在使用的数据库的问题。 –

回答

0

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

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 [email protected]);\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 [email protected]); 
Invoked query with replaced parameters:: (select col_value2 from table2 where x1=-316456543); with result: -1396099308 
+0

谢谢Michal。这很有帮助。 – renGth

+0

我的要求稍有不同。 第二个'set'包含一个concat(),即 set @b = concat(....(从a选择a,其中c = @ a)....)。如果我们分开分开执行,第二个语句会抛出一个错误。 – renGth