Вопрос

У меня странная ситуация с небольшим применением в Java с использованием JDBC-OBDC. Я осматриваю базу данных, используя класс DatabaseMetAdata. Когда я выполняю программу, все работает без каких -либо продуктов. Но когда я хочу отладить, чтобы увидеть значения внутри получения результата, содержащих базу данных java.sql.sqlexection, бросается только в том случае, если я помесчу точку останова в течение некоторого времени. Вот мой код:

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();

Почему я не могу поместить свою точку останова в этом разделе кода ??

Это 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:56 в моем коде называется

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

Спасибо.

Это было полезно?

Решение

Я установил SQL Server, чтобы воспроизвести вашу проблему и проверить ее.

Короткое объяснение

Вы должны прочитать значения ТОЛЬКО ОДНАЖДЫ и в ЗАКАЗ Они появляются в избранном. JDBCODBC - отстой. Во время отладки вы читаете их несколько раз.

Длинное объяснение

Что вы делаете Осмотр объекта состояния в отладчике, что приводит к динамическим результатам.

В этом случае это sun.jdbc.odbc.JdbcOdbcResultSet и выполнять выражение resultSet.getString(...) много раз. В первый раз это сработает (в случае, если ваша точка останова приостанавливает поток до того, как будет спросить результаты). Затем во второй раз, когда вы (или ваш отладчик) снова проверяете ценность выражения, getString() Метод называется опять таки и этот метод меняет внутреннее состояние ResultSet объект.

Хотя название метода предполагает, что это простой получение, это не так. Это делает больше, чем это. На самом деле он может извлечь данные из базы данных, изменить свои счетчики внутренней позиции и т. Д. Вы не можете выполнить методы Getter несколько раз.

Драйвер ODBC - очень плохая вещь и низкого качества. Ожидайте странного поведения и других драконов. Вы можете получить некоторую информацию отладки, включив отслеживание JDBCODBC. Это делается путем установки LogWriter На Drivermanager, до активации мостика JDBCODBC:

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

Затем вы получите многословную отладку вывода JDBCODBC-драйвера, как следующее. Это может помочь вам отладить проблему, которую у вас есть. При отладке просто убедитесь, что хранить данные, полученные из объектов ResultSet в локальных объектах, чтобы вы могли осмотреть их несколько раз в отладчике.

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. Как вы можете видеть в первой строке, это то, что распечатано на консоли, когда я осмотрел getString() метод

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)

Другие советы

Да, отладчик работает в другой ветке, чем метаданные, полученные con.getMetaData();... Итак, вы знаете, это другая транзакция с другими метаданными.

Ну, хорошо, это было бы моим первым предположением. Я не изучал исходный код драйвера OBDC, чтобы подтвердить.


РЕДАКТИРОВАТЬ: Спасибо за Mhaller, отличное замечание, сделанное вторым взглядом/угадайте: вы называете преждевременно (), оно имеет значение после некоторой работы с результатами. Копия из Javadoc

 * Note that you must first call one of the getter methods
 * on a column to try to read its value and then call
 * the method <code>wasNull</code> to see if the value read was
 * SQL <code>NULL</code>.

Фу, я отстой сегодня!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top