不知道為何使用 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);
