Что, если столбец имеет тип NUMBER
, и я вызываю getBoolean()
по ResultSet
? Что он возвращает?
В javadoc для интерфейса не указан тип NUMBER
.
java.sql.ResultSet
Если назначенный столбец имеет тип данных CHAR или VARCHAR и содержит «0» или имеет тип данных BIT, TINYINT, SMALLINT, INTEGER или BIGINT и содержит 0, возвращается значение false. Если назначенный столбец имеет тип данных CHAR или VARCHAR и содержит «1» или имеет тип данных BIT, TINYINT, SMALLINT, INTEGER или BIGINT и содержит 1, возвращается значение true.
Документация по расширению Oracle не подробно описывает
Ява 8
Версия драйвера JDBC com.oracle.database.jdbc:ojdbc6:11.2.0.4
База данных Oracle 11g Enterprise Edition, выпуск 11.2.0.3.0 — 64-битная производственная версия
В этом дело? IDE по какой-то причине не загружает исходники, так что я думаю, это все, что мы можем сделать. Я не понимаю, что делает этот код
// oracle.jdbc.driver.NumberCommonAccessor#getBoolean
boolean getBoolean(int var1) throws SQLException {
boolean var2 = false;
if (this.rowSpaceIndicator == null) {
SQLException var6 = DatabaseError.createSqlException(this.getConnectionDuringExceptionHandling(), 21);
var6.fillInStackTrace();
throw var6;
} else {
if (this.rowSpaceIndicator[this.indicatorIndex + var1] != -1) {
byte[] var3 = this.rowSpaceByte;
int var4 = this.columnIndex + this.byteLength * var1 + 1;
byte var5 = var3[var4 - 1];
var2 = var5 != 1 || var3[var4] != -128;
}
return var2;
}
}
«В любом случае вы можете сказать, что полагаться на недокументированное поведение — плохая идея, но я считаю getBoolean()
более семантически привлекательным». - Если бы я читал ваш код, я бы не стал. Подсказка: важно не только то, что вы считаете «семантически привлекательным». Подумайте, что происходит, когда кто-то другой сталкивается с частью вашего кода, где вы вызываете getBoolean
в столбце NUMBER
, и у него возникают те же «сомнения», что и у вас. Что они делают? Они спускаются в кроличью нору, просматривая javadocs, гугля, задавая вопросы SO и так далее. Не лучше ли этого избежать?
Вам следует попробовать и добавить результаты к своему вопросу.
связанный (очень активный вопрос) Есть ли какой-либо логический тип в базах данных Oracle?
из Руководства разработчика Oracle JDBC 11 Доступ к данным Oracle и манипулирование ими: «Метод getBoolean поддерживается только для числовых столбцов. При применении к этим столбцам getBoolean интерпретирует любое нулевое значение как ложное, а любое другое значение как истинное».
Из Oracle 19 Руководство разработчика JDBC: 11 Доступ к данным Oracle и манипулирование ими
getBoolean
Поскольку не существует
BOOLEAN
типа базы данных, при использованииgetBoolean
всегда происходит преобразование типа данных. МетодgetBoolean
поддерживается только для числовых столбцов. При применении к этим столбцамgetBoolean
интерпретирует любое нулевое значение какfalse
, а любое другое значение какtrue
. При применении к столбцу любого другого типаgetBoolean
вызывает исключениеjava.lang.NumberFormatException
.
Примечание. Версия Oracle 11g «Руководства разработчика JDBC» для Oracle, похоже, больше не существует, а ссылки на нее в оставшейся документации Oracle 11g не работают, поэтому документированное поведение такой старой, неподдерживаемой версии продукта найти сложно (невозможно?). Лучшим способом может быть тестирование поведения с помощью вашего драйвера (а затем добавление интеграционного теста в ваш набор тестов, чтобы вы могли отслеживать любые изменения в поведении при обновлении драйверов). В противном случае обновите базу данных до современной поддерживаемой версии.
Для справки: спецификация JDBC 4.3 (Приложение B.6) перечисляет следующие типы JDBC, поддерживаемые для getBoolean()
.
TINYINT, SMALLINT, INTEGER,
BIGINT, REAL, FLOAT, DOUBLE,
DECIMAL, NUMERIC, BIT,
BOOLEAN, CHAR, VARCHAR,
LONGVARCHAR
Обратите внимание, что здесь указан NUMERIC
, а не NUMBER
. В javadoc для java.sql.Types говорится, что NUMERIC
:
Константа в языке программирования Java, иногда называемая кодом типа, которая идентифицирует общий тип SQL
NUMERIC
.
Когда я просматриваю различные руководства по SQL и т. д., я вижу NUMERIC
, а не NUMBER
в большинстве диалектов SQL. Исключением является то, что синтаксис Oracle SQL поддерживает как NUMERIC
(ANSI-совместимый), так и NUMBER
.
Так что же это значит? Ну, если предположить, что:
NUMBER
в Oracle является синонимом NUMERIC
, атогда мы можем сделать вывод, что NUMBER
поддерживается для getBoolean()
.
Однако я остаюсь при своем предыдущем комментарии. Учитывая «свободные» операторы в javadocs для getBoolean()
, возможно, было бы неплохо избегать их использования для столбцов Oracle NUMBER
.
Почему?
Чтобы никто, прочитавший ваш код, не оказался в этой кроличьей норе!
См. docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/… о том, как типы данных ANSI фактически реализуются в Oracle - NUMBER
не является синонимом NUMERIC
, это другой в обход NUMERIC
является синонимом NUMBER
(Примечание: ранние версии Oracle предшествовали стандарту ANSI, и Oracle сохранила обратную совместимость)
Что бы ни. Если X — синоним Y, то Y — синоним X. Независимо от того, какое слово вошло в употребление первым. (Проверьте определение синонима в словаре; например, merriam-webster.com/dictionary/synonym.) И этот вопрос касается JDBC и того, как >он< обрабатывает типы SQL.
Дело в том, что вы не можете предполагать, что соблюдается стандартное поведение NUMERIC
ANSI - вы должны предполагать, что соблюдается любое специфическое для Oracle поведение для типа данных NUMBER
, и, как указано в документации Oracle JDBC, использование getBoolean
в строке будет вызвать исключение. (И, если вы будете педантичны в отношении терминологии, в документации, на которую я ссылался в предыдущем комментарии, указано, что типы данных ANSI преобразуются в эквивалентный тип данных Oracle - поэтому запись NUMERIC
в операторе DDL всегда даст NUMBER
) .
Но что, если мы обновимся до 23, столбцы получат BOOLEAN
и код сломается? getBoolean()
более устойчив в этом отношении. getDouble()
, например, в большей степени зависит от фактического типа столбца
Вы можете сказать, что в любом случае полагаться на недокументированное поведение — плохая идея, но я считаю
getBoolean()
более семантически привлекательным. Дело не в том, что любой здравомыслящий человек в Oracle изменил бы такое поведение, каким бы оно ни было, даже если оно не задокументировано. Довольно немыслимо