ODBC 错误:字符串或缓冲区长度无效 - Microsoft Server 2008 32 位与 2008 R2 64 位

发布于 2024-10-08 09:31:17 字数 1298 浏览 10 评论 0原文

尝试使用 SQL Server Native Client 10.0 通过 ODBC 系统 DSN 从 Java 6 控制台应用程序连接到 Microsoft Windows Server 2008 R2 64 位系统上的 Microsoft SQL Server 2008 R2。源代码如下:

        try
        {
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
            String srcURL = "jdbc:odbc:FOO";
            if (dbc == null)
            {
                dbc = DriverManager.getConnection(srcURL);
                dbc.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
            }
            else
            {
                dbc.close();
                dbc = DriverManager.getConnection(srcURL);
                dbc.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
            }
        }
        catch (ClassNotFoundException cx)
        {
            System.out.println("class not found");
        }
        catch (SQLException sx)
        {
            System.out.println("SQL Exception: " + sx);
            log.info("SQL Exception: " + sx);
    }

抛出错误

java.sql.Exception [Microsoft] [ODBC 驱动程序管理器] 字符串缓冲区长度无效

令人抓狂的是,相同的代码,并且以完全相同的方式配置 ODBC 系统 DSN,WORKS 与 MS Server 2008 32 位(非-R2) 和 MS SQL Server 2008 R2。两个系统之间的 Microsoft ODBC 驱动程序 dll 是不同的版本,6.0.xxxx 与 6.1.xxxx,我怀疑这是罪魁祸首。

Attempting to connect from Java 6 console app to Microsoft SQL Server 2008 R2 on an Microsoft Windows Server 2008 R2 64bit system via an ODBC System DSN using SQL Server Native Client 10.0. The following source code:

        try
        {
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
            String srcURL = "jdbc:odbc:FOO";
            if (dbc == null)
            {
                dbc = DriverManager.getConnection(srcURL);
                dbc.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
            }
            else
            {
                dbc.close();
                dbc = DriverManager.getConnection(srcURL);
                dbc.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
            }
        }
        catch (ClassNotFoundException cx)
        {
            System.out.println("class not found");
        }
        catch (SQLException sx)
        {
            System.out.println("SQL Exception: " + sx);
            log.info("SQL Exception: " + sx);
    }

Throws error

java.sql.exception [Microsoft] [ODBC Driver Manager] invalid string buffer length

Maddeningly, the same code, with and ODBC System DSN configured in the exact same way, WORKS with MS Server 2008 32bit (non-R2) and MS SQL Server 2008 R2. The Microsoft ODBC driver dlls between the two systems are different versions, 6.0.xxxx vs 6.1.xxxx, which I suspect is the culprit.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冷情 2024-10-15 09:31:17

是的,ODBC 管理器版本应该是问题所在。下面是我遇到的问题和我想到的解决方案,希望对其他人也有帮助。

当尝试从部署到 Jboss 4.x 的应用程序对系统 ODBC DSN(MS Access .mdb 文件)运行查询时,我收到相同的错误:“SQL 状态 [S1090];错误代码 [0];[Microsoft][ODBC 驱动程序Manager] Windows Server R2 中的字符串或缓冲区长度无效。

我在两台不同的 Windows Server R2 计算机上重现了相同的错误。在 Windows Server Standard(我猜是 R1)和 Windows 7 Professional x64 上,该问题无法重现。

此外,在同一 Windows Server R2 上尝试直接连接(从独立应用程序)时,我没有遇到此问题。如果应用程序无法连接/检测数据源,您将收到一条错误消息,指出不存在此类 DSN 名称或未找到该名称。当尝试将空查询发送到 ODBC 数据源(注册数据源名称 - DSN)时,会引发相同的错误消息。所以我猜 ODBC 得到一个空查询,尝试针对 DS 执行,结果是:无效的字符串或缓冲区长度。

由于我可以读取使用给定 DSN 注册为 ODBC DS 的 .mdb 文件,并且从独立应用程序查询它时不会出现此错误,因此我将创建一个独立应用程序,该应用程序将通过以下方式读取 .mdb 文件: ODBC 并将其内容写入 .csv 文件,Jboss 应用程序将读取该文件。

如果有人找到更好的解决方案,请告诉我。

Yeah the ODBC Manager version should be the problem. Below is the problem I ran into and the solution I thought of, hope it might be of help to someone else too.

When trying to run query against System ODBC DSN (MS Access .mdb file) from an app deployed to Jboss 4.x, I get same error: "SQL state [S1090]; error code [0]; [Microsoft][ODBC Driver Manager] Invalid string or buffer length" in Windows Server R2.

I reproduced the same error on 2 different Windows Server R2 machines. On Windows Server Standard (I guess R1) and Windows 7 Professional x64 the problem is not reproducible.

Further more, on the same Windows Server R2 when trying to connect directly (from a standalone app), I don't get this problem. If the application won't connect/detect the data source, you'd get an error saying that there is no such DSN name or it's not found. The same error message is thrown when trying to send an empty query to ODBC Data Source (registered Data Source Name - DSN). So i guess the ODBC gets an empty query which tries to execute against the DS and the result is: Invalid string or buffer length.

Since I can read the .mdb file registered as a ODBC DS with given DSN, and I don't get this error when querying it from the standalone app, I'm going to make a standalone app that will read the .mdb file through ODBC and write its content to a .csv file, which the Jboss apps will read.

If anyone finds a better solution, please let me know.

一张白纸 2024-10-15 09:31:17

JDBC-ODBC 桥本机代码问题。
本机代码使用无效的 BufferLength 参数调用 ODBC 函数 SQLGetData。
此问题仅发生在 64 位 jvm 上。据我所知,它可能发生在所有 jdks 上:从 1.0 到 1.7。

BufferLength 是一个 8 字节的 SQLLEN 参数。在 64 位 jvm 中,高 4 字节未初始化,这是根本原因。
目前没有解决方法,Oracle 拒绝解决这个问题,尽管我通过 oracle metalink 网站报告了这个问题。

A issue of JDBC-ODBC bridge native codes.
The native codes invoke ODBC function SQLGetData with a invalid BufferLength parameter.
This problem happens on 64bit jvm only. As I know, it can happen on all jdks: since 1.0 to 1.7.

The BufferLength is a 8 bytes SQLLEN parameter. The high 4 bytes is left uninitialized in 64bit jvm, that the root cause.
Currently there is no workaround, and Oracle refuse to fix this issue, even though I reported it via oracle metalink website.

山川志 2024-10-15 09:31:17

这是一个java bug,至少升级到java 1.7.70。

this is a java bug, upgrade to java 1.7.70 at least.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文