不知道為何使用 Microsoft JDBC Driver for SQL Server 驅動時,sql語句不帶參數沒有問題,但是如果帶參數且使用 getParameterMetaData 就會提示某個關鍵字附件有錯誤!下載了最新的 Microsoft JDBC Driver 4.1 for SQL Server 還是一樣的錯誤。難道是沒有設置好?做了下測試:
1、簡單的語句測試,getParameterMetaData 對 between 支持有問題
//----------------------- dbTest 執行語句方法 ------------------ private void dbTest(String sql) { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; ParameterMetaData pmd = null; try { conn = DBHelper.getConnection(); pstmt = conn.prepareStatement(sql); pmd = pstmt.getParameterMetaData(); // 關鍵是這個方法出問題 pstmt.setObject(1, 100); pstmt.setObject(2, 1000); rs = pstmt.executeQuery(); if(rs.next()) { System.out.println(rs.getString(1)); } } catch (SQLException e) { e.printStackTrace(); } finally { DBHelper.release(conn, pstmt, rs); } } //--------------------------測試1--------------------------------- // 執行下面between語句,如果dbTest中啟用pstmt.getParameterMetaData(),那么會報錯,(com.microsoft.sqlserver.jdbc.SQLServerException: 關鍵字 'between' 附近有語法錯誤);但是如果注釋掉 pmd = pstmt.getParameterMetaData(),那么執行正常。 String sql1 = "select * from users where userId between ? and ?"; dbTest(sql1); //--------------------------測試2--------------------------------- // 將between替換成等效的(>= and <=),無論何種情況執行都正常 String sql2 = "select * from users where userId >= ? and userId <= ?"; dbTest(sql2);
2、子查詢測試
// 不用 between,用 >= and <= 等效替換 // 啟用 pmd = pstmt.getParameterMetaData(),報錯(com.microsoft.sqlserver.jdbc.SQLServerException: 關鍵字 'WHERE' 附近有語法錯誤);但是如果不用pstmt.getParameterMetaData()這個方法,就正常執行了! String sql3 = "select * from (select userId, userName from users) as tp where tp.userId >= ? and tp.userId <= ?"; dbTest(sql3);
3、換成jtds驅動沒有任何問題。
歸納下問題:
(1)不用 getParameterMetaData 方法,任何sql語句執行都沒有任何問題,關鍵是我要用dbutils,但是這個庫使用了getParameterMetaData 方法。怎么解決。
(2)使用getParameterMetaData方法時,不帶參數的sql語句執行沒有問題,但是如果帶參數而且使用了between或者有子查詢,那么就出錯。為什么?是不是哪兒的設置問題?
==================================================================================
寫了這些疑問查找了幾天,后來仔細查看了Microsoft JDBC Driver for SQL Server的文檔,才發現上面已經有了相關的說明。
在“使用參數元數據”一節中有如下提示:
SQLServerParameterMetaData 類和預定義的語句一起使用時有一些限制。JDBC 驅動程序支持 SELECT、DELETE、INSERT 和 UPDATE 語句。但是,這些語句不能包含子查詢。此外,JDBC 驅動程序還支持使用 IN、IS 和 LIKE 謂詞。對於搜索條件,JDBC 驅動程序支持使用 IS、<、>、LIKE、>=、<=、NOT IN、<>、!>、!< 和 != 比較運算符。不支持 FREETEXT 運算符。
dbutils使用QueryRunner時,可以設置pmdKnownBroken為true,dbutils設置參數時將繞過 getParameterMetaData 方法:
QueryRunner run = new QueryRunner(true); QueryRunner run = new QueryRunner(dataSource, true);