[Access][Microsoft][ODBC 驅動程序管理器] 無效的字符串或緩沖區長度 Invalid string or buffer length


背景描述:

項目中,客戶的工廠有一台檢測產品指標的檢測儀,其檢測結果存儲在本地電腦的Access數據庫中。項目的目的是服務器連接這台電腦,通過rmi的方式進行連接,讀取這台電腦上的Access數據庫的mdb文件中的內容。

Java 在服務器上通過RMI的方式訪問客戶電腦上的Access數據庫中的內容的方法可以參考:https://blog.csdn.net/hongdi/article/details/5482470 中的介紹,很詳細了。

 

錯誤描述:

在讀取客戶電腦上的Access數據庫中的數據時,最開始一切都很正常,從某一時間點開始,報如下錯誤:

 1 java.sql.SQLException: [Microsoft][ODBC 驅動程序管理器] 無效的字符串或緩沖區長度
 2     at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
 3     at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
 4     at sun.jdbc.odbc.JdbcOdbc.SQLGetDataString(Unknown Source)
 5     at sun.jdbc.odbc.JdbcOdbcResultSet.getDataString(Unknown Source)
 6     at sun.jdbc.odbc.JdbcOdbcResultSet.getString(Unknown Source)
 7     at org.objectweb.rmijdbc.RJResultSetServer.getString(RJResultSetServer.java:144)
 8     at sun.reflect.GeneratedMethodAccessor59.invoke(Unknown Source)
 9     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
10     at java.lang.reflect.Method.invoke(Unknown Source)
11     at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
12     at sun.rmi.transport.Transport$2.run(Unknown Source)
13     at sun.rmi.transport.Transport$2.run(Unknown Source)
14     at java.security.AccessController.doPrivileged(Native Method)
15     at sun.rmi.transport.Transport.serviceCall(Unknown Source)
16     at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
17     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
18     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.access$400(Unknown Source)
19     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(Unknown Source)
20     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(Unknown Source)
21     at java.security.AccessController.doPrivileged(Native Method)
22     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
23     at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
24     at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
25     at java.lang.Thread.run(Unknown Source)
26     at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:283)
27     at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:260)
28     at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:161)
29     at org.objectweb.rmijdbc.RJResultSetServer_Stub.getString(Unknown Source)
30     at org.objectweb.rmijdbc.RJResultSet.getString(RJResultSet.java:143)

經查,用戶的電腦的操作系統為64位Windows 7系統。同樣的代碼,當用戶的電腦是32位Windows XP時就好用,不報錯。

程序中讀取數據的代碼如下:

1 String sampNo = rs.getString(1);

經過不斷的查找,終於在這篇帖子上找到了問題的根源:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8038751

是因為Jdk 1.6/7在64位操作系統上JDBC-ODBC橋上的Bug,導致在調用ResultSet.getObject()/getString()的時候隨機並且不定時的報出 [Microsoft][ODBC 驅動程序管理器] 無效的字符串或緩沖區長度 這個錯誤。並不是一定會報錯,可能是正常的運行了一段時間之后才報出來。

這也解釋了為什么當用戶電腦是Windows XP時讀取沒問題,當用戶是Windows 7 64位的時候才會有問題。

 

 

解決方法:
避免使用ResultSet.getObject()/getString(),根據數據庫的類型,如果是數字使用getLong,如果是字符串使用getBytes來進行讀取。比如:
1 String remark = new String(rs.getBytes(4), "gbk");

 

至此,此問題再也沒有再復現過,問題解決!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM