2015-10-06 29 views
0

背景預處理語句了setString增加不必要的單引號字符串

我想一個ArrayList的內容設置成在DB2 SQL語句的IN條款。我正在使用PreparedStatement來構建我的查詢。 這是我們的編碼標準。

我試過#1

我研究了幾種方法來實現這一目標。我第一次使用setArray()作爲展現在這個問題的嘗試:How to use an arraylist as a prepared statement parameter結果是我得到的Err com.ibm.db2.jcc.am.SqlFeatureNotSupportedException: [jcc][t4][10344][11773][3.65.110] Data type ARRAY is not supported on the target server. ERRORCODE=-4450, SQLSTATE=0A502一個錯誤這個障礙後,我轉移到#2

我試了一下#2

然後我嘗試使用Apache Commons StringUtils將ArrayList轉換爲逗號分隔的字符串,就像我需要的IN子句。結果是,這正是我所需要的,我有一個字符串,所有結果都以逗號分隔。

問題:

setString()方法是添加單引號來我的字符串的開頭和結尾。我已經使用了很多次,並且從來沒有這樣做過。 有誰知道是否有解決方法,或使用PreparedStatement的替代?如果我使用String concatenation,我的查詢就可以工作。

代碼(如上所述):

List<String> selectedStatuses = new ArrayList<String>(); //Used to store contents of scoped var 

    //Get Contents of Checkbox which are in the form of a List 
    selectedStatuses = (List) viewScope.get("selectedStatuses"); 

    String selectedStatusesString = StringUtils.join(selectedStatuses, ","); 

    .... WHERE ATM_DET_ATM_STAT IN (?)"; 
    ps.setString(1, selectedStatusesString); 

log值表示字符串的正確值

DEBUG:selectedStatusesString:'OPEN','CLOSED','WOUNDED','IN PROGRESS'

視覺不正確的結果的

enter image description here

在開頭和結尾的引號的問題。

+1

這看起來你試圖通過將一個參數連接成一個長字符串來將多個參數傳遞給一個參數。參見[問題17842211](http://stackoverflow.com/questions/17842211/how-to-use-an-arraylist-as-a-prepared-statement-parameter) – matt

+0

它是使用StringUtils的後一個字符串。如果它不是一個字符串,它不會編譯。我確實看到了這個問題,並在'我試過#1'部分中引用了它。在得到奇怪的DB2錯誤後,我無法使setArray()正常工作。 –

+0

你有沒有在你的論點引號沒有嘗試它?是的,我看到你正在將參數列表轉換爲單個字符串。準備好的陳述應該是這樣,以至於你不能這樣做。 setArray應該是正確的方法。我會低估那一個,但我不能確定它現在被打破。 – matt

回答

1

對於IN條款的工作,你,你有值需要儘可能多的標記:

String sql = "SELECT * FROM MyTable WHERE Stat IN (?,?,?,?)"; 
try (PreparedStatement stmt = conn.prepareStatement(sql)) { 
    stmt.setString(1, "OPEN"); 
    stmt.setString(2, "CLOSED"); 
    stmt.setString(3, "WOUNDED"); 
    stmt.setString(4, "IN PROGRESS"); 
    try (ResultSet rs = stmt.executeQuery()) { 
     // use rs here 
    } 
} 

既然你有值的動態列表,你需要這樣做:

List<String> stats = Arrays.asList("OPEN", "CLOSED", "WOUNDED", "IN PROGRESS"); 

String markers = StringUtils.repeat(",?", stats.size()).substring(1); 
String sql = "SELECT * FROM MyTable WHERE Stat IN (" + markers + ")"; 
try (PreparedStatement stmt = conn.prepareStatement(sql)) { 
    for (int i = 0; i < stats.size(); i++) 
     stmt.setString(i + 1, stats.get(i)); 
    try (ResultSet rs = stmt.executeQuery()) { 
     // use rs here 
    } 
} 
+0

優秀!謝謝你,先生。底線:setString()不適用於IN語句中的多個標記。 –

+1

Ehh ....底線:所有'setXxx(index,value)'方法用於設置*第一個參數標識的標記的*值。 – Andreas

0

使用兩個撇號''獲得DB2上一個單引號,根據DB2 Survival Guide。然後調用.setString()。