为什么我不能调试DatabaseMetaData? [英] Why I cannot debug a DatabaseMetaData?

查看:108
本文介绍了为什么我不能调试DatabaseMetaData?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用JDBC-OBDC的Java小程序中,我遇到了一个奇怪的情况。我正在使用DatabaseMetaData类检查数据库。当我执行程序时,一切正常,没有任何问题。但是,当我想调试以查看包含DatabaseMetaData的Resulset中的值时,仅当我在while内放置一个断点时,才会引发java.sql.SQLException。这是我的代码:

I've a strange situation with a little application in Java using a JDBC-OBDC. I'm inspecting a Database using the DatabaseMetaData Class. When I execute the program, everything works without anyproblem. But when I want to debug to see the values inside the Resulset containing the DatabaseMetaData a java.sql.SQLException is thrown only if I put a breakpoint within the while. Here's my code:

DatabaseMetaData patrol = con.getMetaData();
ResultSet answer = patrol.getTables(null, null, null, null);
        while(answer.next()) {
            if (answer.wasNull() == false) {
                tableNamesAsOne = tableNamesAsOne + answer.getString("TABLE_NAME") + " ";
            }
        }
        answer.close();

为什么我不能在此代码段中放置断点?

Why I cannot put my breakpoint in this section of code??

这是printStackTrace。

This is the printStackTrace.

Exception in thread "main" java.sql.SQLException: No data found
    at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
    at sun.jdbc.odbc.JdbcOdbc.SQLGetDataString(Unknown Source)
    at sun.jdbc.odbc.JdbcOdbcResultSet.getDataString(Unknown Source)
    at sun.jdbc.odbc.JdbcOdbcResultSet.getString(Unknown Source)
    at sun.jdbc.odbc.JdbcOdbcResultSet.getString(Unknown Source)
    at Snooper.inspect(Snooper.java:56)
    at Snooper.<init>(Snooper.java:26)
    at Snooper.createAndShowGUI(Snooper.java:112)
    at Snooper.main(Snooper.java:125)

Line Snooper.java:我代码中的Java 56是指

Line Snooper.java:56 in my code refers to

tableNamesAsOne = tableNamesAsOne + answer.getString("TABLE_NAME") + " ";

谢谢。

推荐答案

我已经安装了SQL Server以重现您的问题并进行验证。

I have installed SQL Server to reproduce your problem and verify it.

您必须读取值仅一次,并且在 ORDER 中它们将出现在SELECT中。 JdbcOdbc很烂。调试时,您会多次读取它们。

You must read the values ONLY ONCE and in the ORDER they appear in the SELECT. JdbcOdbc sucks. While debugging, you're reading them multiple times.

您正在做的是在调试器中检查有状态对象,从而获得动态结果。

What you are doing is inspecting a stateful object in the debugger, which leads to dynamic results.

在这种情况下,它是 sun.jdbc.odbc.JdbcOdbcResultSet 并执行表达式 resultSet.getString(...)多次。第一次,它将起作用(以防您的断点在询问resultSet之前挂起Thread)。然后,第二次您(或调试器)再次检查表达式的值时, getString()方法再次称为 ,该方法更改 ResultSet 对象的内部状态

In this case it's the sun.jdbc.odbc.JdbcOdbcResultSet and executing the expression resultSet.getString(...) multiple times. The first time, it will work (in case your breakpoint suspends the Thread before the resultSet is asked). Then, the second time you (or your debugger) inspects the value of the expression again, the getString() method is called again and this method changes the internal state of the ResultSet object.

尽管该方法的名称表明它很简单,但事实并非如此。它的作用远不止这些。它实际上可能从数据库中检索数据,更改其内部位置计数器等。您不能多次执行getter方法。

Although the method's name suggests it's a simple getter, it's not. It does more than that. It may actually retrieve the data from the database, change its internal position counters etc. You cannot execute the getter methods multiple times.

ODBC驱动程序是一件非常糟糕的事情,并且低质量的。期待奇怪的行为和其他巨龙。您可以通过启用JdbcOdbc跟踪来获取一些调试信息。这是通过在激活JdbcOdbc-Bridge之前在DriverManager上设置 LogWriter 来完成的:

The ODBC Driver is a very bad thing and of low quality. Expect strange behavior and other dragons. You can get some debug information by enabling JdbcOdbc Tracing. That is done by setting a LogWriter on the DriverManager, before the JdbcOdbc-Bridge is activated:

java.sql.DriverManager.setLogWriter(new PrintWriter(System.out));

然后,您将获得JdbcOdbc-Driver的详细调试输出,如下所示。它可以帮助您调试问题。调试时,只需确保将从ResultSet对象中检索到的数据存储在本地对象中,以便可以在调试器中对其进行多次检查。

Then, you will get verbose debugging output of the JdbcOdbc-Driver like the following. It may help you to debug the problem you have. When debugging, just ensure to store the data retrieved from the ResultSet objects in local objects, so you can inspect them multiple times in the debugger.

DriverManager.getConnection("jdbc:odbc:testdbodbc")
JdbcOdbcDriver class loaded
registerDriver: driver[className=sun.jdbc.odbc.JdbcOdbcDriver,sun.jdbc.odbc.JdbcOdbcDriver@7b479feb]
DriverManager.initialize: jdbc.drivers = null
JDBC DriverManager initialized
    trying driver[className=sun.jdbc.odbc.JdbcOdbcDriver,sun.jdbc.odbc.JdbcOdbcDriver@7b479feb]
*Driver.connect (jdbc:odbc:testdbodbc)
JDBC to ODBC Bridge: Checking security
No SecurityManager present, assuming trusted application/applet
JDBC to ODBC Bridge 2.0001
Current Date/Time: Wed Jan 26 00:31:27 CET 2011
Loading JdbcOdbc library
Allocating Environment handle (SQLAllocEnv)
hEnv=115724512
Allocating Connection handle (SQLAllocConnect)
hDbc=116219184
Connecting (SQLDriverConnect), hDbc=116219184, szConnStrIn=DSN=testdbodbc
RETCODE = 1
WARNING - Generating SQLWarning...
SQLWarning: reason([Microsoft][ODBC SQL Server Driver][SQL Server]Changed database context to 'master'.) SQLState(01000) vendor code(5701)
SQLWarning: reason([Microsoft][ODBC SQL Server Driver][SQL Server]Changed language setting to us_english.) SQLState(01000) vendor code(5703)
*Connection.getMetaData
*DatabaseMetaData.getDriverName
Get connection info string (SQLGetInfo), hDbc=116219184, fInfoType=6, len=300
SQLSRV32.DLL
*DatabaseMetaData.getDriverVersion
Get connection info string (SQLGetInfo), hDbc=116219184, fInfoType=7, len=300
06.01.7600
*DatabaseMetaData.getDriverName
Get connection info string (SQLGetInfo), hDbc=116219184, fInfoType=6, len=300
SQLSRV32.DLL
Driver name:    JDBC-ODBC Bridge (SQLSRV32.DLL)
*DatabaseMetaData.getDriverVersion

PS这是复制的异常,包括JDK 1.6.0_22的Sun代码的行号。如第一行所示,这是我检查 getString()方法时在控制台上打印的内容。

P.S. And this was the reproduced exception, including line numbers of the Sun code for JDK 1.6.0_22. As you can see in the first line, this is what is printed out on the console when I inspected the getString() method.

Get string data (SQLGetData), hStmt=108067024, column=3, maxLen=257
RETCODE = 100
ERROR - No data found
java.sql.SQLException: No data found
at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7138)
at sun.jdbc.odbc.JdbcOdbc.SQLGetDataString(JdbcOdbc.java:3907)
at sun.jdbc.odbc.JdbcOdbcResultSet.getDataString(JdbcOdbcResultSet.java:5698)
at sun.jdbc.odbc.JdbcOdbcResultSet.getString(JdbcOdbcResultSet.java:354)
at sun.jdbc.odbc.JdbcOdbcResultSet.getString(JdbcOdbcResultSet.java:411)
at sandbox.DatabaseMetadataTest.testDBMetadata(DatabaseMetadataTest.java:27)

这篇关于为什么我不能调试DatabaseMetaData?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆