2017-08-12 94 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