Есть ли логический тип в базах данных Oracle?


250

Существует ли какой-либо логический тип в базах данных Oracle, похожий на BITтип данных в Ms SQL Server?


7
К сожалению, Oracle не полностью поддерживала стандарт ANSI SQL: 1999 ( en.wikipedia.org/wiki/SQL:1999 ), когда он был представлен.
Джеффри Кемп

2
Альтернативная точка зрения (почему SQL не должен иметь логический тип): vadimtropashko.wordpress.com/2010/09/16/…
Джеффри Кемп

7
@JeffreyKemp Этот блог бессмысленный. Тот факт, что некоторые логические значения могут быть вычислены на основе других полей в таблице, не означает, что все логические поля могут быть вычислены. Например, «is_trusted_customer», где это верно, если и только если человек решит: «Я доверяю этому человеку».
Джейкоб

2
@JeffreyKemp Поздравляем, вы только что заново изобрели логические значения в стиле C (где intвместо этого вы используете s). Мы обязательно должны вернуться к тем, что в коде. Кроме того, аргумент полностью распадается, если типы данных между столбцами таблицы и столбцами результата (из a SELECT) являются общими, поскольку абсолютно логично возвращать логическое значение в качестве вычисленного результата, иногда даже с учетом остальной части аргумента.
jpmc26

2
Да. Больше типов данных, таких как логические значения, дадут более точную выразительную силу - вы не получите от меня никаких аргументов в этом отношении. Я просто рад, что у нас, по крайней мере, есть DATEтип - представьте себе, что нужно постоянно иметь дело со строковыми представлениями дат :)
Джеффри Кемп

Ответы:


278

Мало того, что логический тип данных отсутствует в Oracle SQL (не PL / SQL), но у них также нет четкой рекомендации о том, что вместо этого использовать. Смотрите эту ветку на асктоме От рекомендации CHAR(1) 'Y'/'N'они переключаются наNUMBER(1) 0/1 то, когда кто-то указывает, что это 'Y'/'N'зависит от английского языка, в то время как, например, немецкие программисты могут использовать 'J'/'N'вместо этого.

Хуже всего то, что они защищают это глупое решение так же, как они защищают ''=NULLглупость.


9
1/0, если не двусмысленно, по крайней мере менее двусмысленно.
Адам Муш

15
Но '' = NULL является ложным! «ЕСТЬ НУЛЬ - это правда. :)
Джим Дэвис

4
Майкл-О: Я видел это несколько раз. Для меня это 0/1 все время, но другие программисты предпочитают J / N. (Я живу в немецкоязычной стране)
Эрих Кицмюллер

11
@Irfy Недавно я увидел Nи Fиспользовал, потому что ONи OFFначинаю с одной и той же буквы ...
JimmyB

7
Можно утверждать, что в качестве замены логического значения «T» / «F» имеет еще больший смысл
Эрих Кицмюллер

56

Нет.

Можешь использовать:

IS_COOL NUMBER(1,0)

1 - true
0 - false

--- наслаждайся оракулом

Или используйте символ Y / N, как описано здесь


6
Я предпочитаю char (1), потому что он занимает меньше места. Вы можете проверить это следующим образом: create table testbool (boolc char(1), booln number(1)); insert into testbool values ('Y', 1 ); select dump(boolc), dump(booln) from testbool; этот CHAR хранится: Typ=96 Len=1: 89и этот NUMBER: как Typ=2 Len=2: 193,2минимум в 12c, NUMBER (1) может использовать 2 байта ...
phil_w

38

Согласно ответам Ammoq и kupa, мы используем число (1) с значением по умолчанию 0 и не допускаем нулевые значения.

вот колонка добавления для демонстрации:

ALTER TABLE YourSchema.YourTable ADD (ColumnName NUMBER(1) DEFAULT 0 NOT NULL);

Надеюсь, это кому-нибудь поможет.


17
Обратите внимание, что вы также можете хранить -1 там. Вы можете добавить проверочное ограничение, чтобы ограничить значения 0 и 1.
Дэвид Олдридж

@DavidAldridge В логической логике любое число, отличное от 0 (FALSE), равно 1 (TRUE), поэтому не имеет значения, какое число сохраняется, что устраняет необходимость в проверочном ограничении. Добавление функции, которая возвращает логическое значение из int, тривиально:boolean intToBool(int in) { return (in != 0); }
Agi Hammerthief

3
@AgiHammerthief Верно, но если вы хотите найти строки, используя предикат для «логического» столбца, я бы лучше знал, что мои варианты - ColumnName = 0или ColumnName = 1, а не ColumnName = 0или ColumnName <> 0. Семантика последнего не дружественна программисту. Я также хотел бы сделать его более простым для оптимизатора запросов, имея два значения.
Дэвид Олдридж

14

Не на уровне SQL, и это жаль, хотя есть один в PLSQL, хотя


13

Нет, в базе данных Oracle нет логического типа, но вы можете сделать это следующим образом:

Вы можете поставить проверочное ограничение на столбец.

Если в вашей таблице нет контрольного столбца, вы можете добавить его:

ALTER TABLE table_name
ADD column_name_check char(1) DEFAULT '1';

Когда вы добавляете регистр, по умолчанию этот столбец получает 1.

Здесь вы ставите проверку, ограничивающую значение столбца, просто ставьте только 1 или 0

ALTER TABLE table_name ADD
CONSTRAINT name_constraint 
column_name_check (ONOFF in ( '1', '0' ));

9

Нет, не существует типа boolean, но вместо этого вы можете использовать 1/0 (номер типа), или 'Y' / 'N' (тип char), или 'true' / 'false' (тип varchar2).



4

Обычный прием, позволяющий сэкономить место, - хранить логические значения в виде Oracle CHAR , а не NUMBER:


4
CHAR (1) и VARCHAR2 (1) идентичны в использовании пространства.
Тони Эндрюс

3
Как я узнал здесь, docs.oracle.com/cd/E17952_01/refman-5.5-en/char.html когда мы рассказываем один символ, существует разница только между char и varchar - char использует 1 байт, но varchar использует 1 байт для пустого пространства + 1 байт для одного символа -> varchar (varchar2) использует 2 байта для 1 символа <когда char использует только 1 байт
Артем Борисов

@ Artem.Borysov: это руководство для MySQL, а не для базы данных Oracle
a_horse_with_no_name

3

Просто потому, что никто еще не упомянул об этом: использование RAW (1) также кажется обычной практикой.


1
Функция raw (1) хороша тем, что пользователь не может предположить, что в ней, а человек, выполняющий запрос, должен понять, что находится в столбце raw (1), и перевести его во что-то осмысленное.
Джейкоб

13
<sarcasm> Да, это так здорово, что вы не можете написать переносимый код jdbc с его помощью. </
sarcasm

@jacob - <сарказм> Это потрясающая идея! Мы должны избавиться от всех других типов данных и хранить все в столбцах RAW! Тогда НИКТО не может произвольно неверно истолковать данные! </ Sarcasm>
Боб Джарвис - Восстановить Монику

Представьте, если бы в oracle был какой-то способ определить типы данных, чтобы мы могли создать тип bool, заключающий в себе тип «raw (1)», назвав его bool или boolean. Затем мы можем определить функцию для печати «истина» или «ложь» в зависимости от содержимого.
Джейкоб

-1
DECLARE
error_flag  BOOLEAN := false;
BEGIN

error_flag := true;
--error_flag := 13;--expression is of wrong type

  IF error_flag THEN 

UPDATE table_a SET id= 8 WHERE id = 1;

END IF;
END;

Этот пример работает. Я также заметил, что могу работать только с логическими типами в PL / SQL. Булевых вызовов в SQL нет и выдает недопустимую ошибку реляционного оператора.
Ричард Паскуаль
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.