Интересно, что булевы типы были введены только поздно в стандарте SQL, а именно в SQL: 1999 . Даже сегодня не все базы данных изначально поддерживают типы BOOLEAN
или BIT
. Самое главное, мы все еще можем ждать их в Oracle некоторое время. Вот точка зрения «Спроси Тома» 2002 года на эту тему: https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:6263249199595
Oracle. Почему ты не логический?
Люди обошли это ограничение, используя вместо этого числовые или строковые литералы. Например, Y / N
, Y / N
, T / F
или стандарт SQL 'true' / 'false'
.
Booleans в JDBC
С точки зрения API JDBC логические значения могут быть установлены как значения связывания с помощью PreparedStatement.setBoolean()
или извлечены из наборов результатов с помощью ResultSet.getBoolean()
и аналогичных методов. Если ваша база данных поддерживает логические значения, boolean
тип Java прекрасно отображается на SQL BOOLEAN
даже если тип Boolean
оболочки Java лучше подходит для соблюдения NULLs
.
Но если вы храните логические значения в столбцах INTEGER
, CHAR(1)
или VARCHAR(1)
, в разных базах данных все выглядит по-разному. Рассмотрим следующий пример:
1
2
3
|
CREATE TABLE booleans ( val char ( 1 ) ); |
И затем, запустите эту программу Java (мы используем jOOQ, чтобы держать вещи краткими)
01
02
03
04
05
06
07
08
09
10
11
|
try { DSL.using(configuration) .execute( "insert into boolean (val) values (?)" , true ); } catch (Exception e) { e.printStackTrace(); } DSL.using(configuration) .fetch( "select * from booleans" ); |
Не все базы данных / драйверы JDBC поддерживают вышеуказанное. Эти базы данных будут запускать вышеуказанную программу:
- Жар-птица (вставляет «Y» или «N»)
- HSQLDB (вставляет «1» или «0»)
- IBM DB2 (вставляет «1» или «0»)
- MariaDB (вставляет «1» или «0»)
- Microsoft Access (вставляет «1» или «0»)
- MySQL (вставляет «1» или «0»)
- Oracle (вставляет «1» или «0»)
- SQL Server (вставляет «1» или «0»)
- Sybase (вставляет «1» или «0»)
… Тогда как эти базы данных будут выдавать исключение:
- CUBRID
- дерби
- H2
- Энгр
- PostgreSQL
- SQLite
Booleans в стандарте SQL
Стоит отметить, что стандарт SQL определяет, как обращаться с boolean
преобразованием в строку в спецификации функции CAST()
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
6.13 <cast specification> [...] 10 ) If TD is fixed-length character string, then let LTD be the length in characters of TD. [...] e) If SD is boolean , then Case: i) If SV is True and LTD is not less than 4 , then TV is 'TRUE' extended on the right by LTD– 4 s. ii) If SV is False and LTD is not less than 5 , then TV is 'FALSE' extended on the right by LTD– 5 <space>s. iii) Otherwise, an exception condition is raised: data exception — invalid character value for cast. |
Таким образом, большинство баз данных с открытым исходным кодом показывают то, что можно интерпретировать как «правильное» поведение, даже если с исторической точки зрения 1/0 должно быть приемлемым поведением. Остерегайтесь этого ограничения при использовании тестовой базы данных с открытым исходным кодом!
Для получения дополнительной информации об этом и базе данных H2, пожалуйста, обратитесь к этой теме в группе пользователей H2 .