Java - JDBC IN Clause set multiple values

有時候我們在做SQL查詢時,會發現我們透過IN語法要過濾出我們要的資料時,若利用程式

塞值進去時,不能單單的使用in (?)放一個參數值進去,得需要個別拆開來另外以頓號做間格

,再去個別設值才可以執行。

在這邊我們將執行下面這段語法:

select * from income_record where ID in (%s)

%s => 我們要設定的參數名稱,由於需依當下有哪些而會有差異

執行的Java程式如下:

在此以Statement來做查詢示範

Connection m_conn = null;
Statement getFilterRecords = null;

String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
String url = "jdbc:sqlserver://localhost:1433;DatabaseName=Homework";
String user = "sa";
String password = "OOXX";

String sql = "select * from income_record where ID in (%s)";
List idLists = Arrays.asList(new String[]{"s001","s002","s001001"});
StringBuilder c_params = new StringBuilder();
int index = 0;
try{
   Class.forName(driver);
   m_conn = DriverManager.getConnection(url, user, password);
   m_conn.setAutoCommit(false);
   //1.
   for(int i = 1 ; i <= idLists.size() ; i++){
      c_params.append(":param_"+i+",");
   }
 
   getFilterRecords = m_conn.createStatement();
   //2.
   sql = String.format(sql, c_params.deleteCharAt(c_params.length()-1));
   for(String id : idLists){
      sql = sql.replace(":param_"+(++index), "'"+id+"'");
   } 
 
   //getFilterRecords.executeUpdate("INSERT INTO 
              //income_record values ('104','09','s001','B',200)");
 
   System.out.println("Execute SQL => "+sql);
 
   m_conn.commit();
 
   ResultSet rs = getFilterRecords.executeQuery(sql);
   while(rs.next()){
      System.out.println(rs.getString("YEAR")+","+rs.getString("MONTH")
                  +","+rs.getString("ID")+","+rs.getString("SOURCE"));
   }
}catch(Exception e){
   e.printStackTrace();
}finally{
 try {
    if(getFilterRecords != null)
       getFilterRecords.close();
    if(m_conn != null)
       m_conn.close();
 } catch (SQLException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
}

1. 組織置換參數,依據當下有多少的值,產生

:param_1, :param_2 ....,

2. 去掉利用StringBuilder串接字串多出來的逗號,利用deleteCharAt method

再來將值去取代掉param_X等名稱

執行結果如下:


PS. 另外也有做commit的測試,預設commit都為自動同步做資料庫的更新操作,也就是說當

您使用executeUpdate的語法後,資料表的資料就會更動。但若setAutoCommit() method 設

成false,則即使您中間已做了更新語法,如果沒執行commit() method也不會有作用囉!

==============================================================
若改以PreparedStatement做示範

延續上面的code

.....
index = 0;
idLists.set(0, "s003");
sql = "select * from income_record where ID in (%s)";
c_params = new StringBuilder();
for(int i = 1 ; i <= idLists.size() ; i++){
 c_params.append("?,");
}
sql = String.format(sql, c_params.deleteCharAt(c_params.length()-1));
getFilterRecords_2 = m_conn.prepareStatement(sql);
for(String id : idLists){
 getFilterRecords_2.setString(++index, id);
}
rs = getFilterRecords_2.executeQuery();
...

得到的結果是一樣的。

不過若要查詢PreparedStatement執行的SQL語法可以透過SQL Server profiler工具來檢視,

如下:



留言