2015-10-06 19 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()。