Java - JDBC IN Clause set multiple values

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

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

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

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

  1. select * from income_record where ID in (%s)

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

執行的Java程式如下:

在此以Statement來做查詢示範

  1. Connection m_conn = null;
  2. Statement getFilterRecords = null;
  3. String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
  4. String url = "jdbc:sqlserver://localhost:1433;DatabaseName=Homework";
  5. String user = "sa";
  6. String password = "OOXX";
  7. String sql = "select * from income_record where ID in (%s)";
  8. List idLists = Arrays.asList(new String[]{"s001","s002","s001001"});
  9. StringBuilder c_params = new StringBuilder();
  10. int index = 0;
  11. try{
  12. Class.forName(driver);
  13. m_conn = DriverManager.getConnection(url, user, password);
  14. m_conn.setAutoCommit(false);
  15. //1.
  16. for(int i = 1 ; i <= idLists.size() ; i++){
  17. c_params.append(":param_"+i+",");
  18. }
  19. getFilterRecords = m_conn.createStatement();
  20. //2.
  21. sql = String.format(sql, c_params.deleteCharAt(c_params.length()-1));
  22. for(String id : idLists){
  23. sql = sql.replace(":param_"+(++index), "'"+id+"'");
  24. }
  25. //getFilterRecords.executeUpdate("INSERT INTO
  26. //income_record values ('104','09','s001','B',200)");
  27. System.out.println("Execute SQL => "+sql);
  28. m_conn.commit();
  29. ResultSet rs = getFilterRecords.executeQuery(sql);
  30. while(rs.next()){
  31. System.out.println(rs.getString("YEAR")+","+rs.getString("MONTH")
  32. +","+rs.getString("ID")+","+rs.getString("SOURCE"));
  33. }
  34. }catch(Exception e){
  35. e.printStackTrace();
  36. }finally{
  37. try {
  38. if(getFilterRecords != null)
  39. getFilterRecords.close();
  40. if(m_conn != null)
  41. m_conn.close();
  42. } catch (SQLException e) {
  43. // TODO Auto-generated catch block
  44. e.printStackTrace();
  45. }
  46. }

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

:param_1, :param_2 ....,

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

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

執行結果如下:


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

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

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

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

延續上面的code

  1. .....
  2. index = 0;
  3. idLists.set(0, "s003");
  4. sql = "select * from income_record where ID in (%s)";
  5. c_params = new StringBuilder();
  6. for(int i = 1 ; i <= idLists.size() ; i++){
  7. c_params.append("?,");
  8. }
  9. sql = String.format(sql, c_params.deleteCharAt(c_params.length()-1));
  10. getFilterRecords_2 = m_conn.prepareStatement(sql);
  11. for(String id : idLists){
  12. getFilterRecords_2.setString(++index, id);
  13. }
  14. rs = getFilterRecords_2.executeQuery();
  15. ...

得到的結果是一樣的。

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

如下:



留言