Esiste un tipo booleano nei database Oracle?


249

Esiste un tipo booleano nei database Oracle, simile al BITtipo di dati in SQL Server?


7
Purtroppo Oracle non supporta completamente lo standard ANSI SQL: 1999 ( en.wikipedia.org/wiki/SQL:1999 ) quando è stato introdotto.
Jeffrey Kemp,

2
Punto di vista alternativo (perché SQL non dovrebbe avere un tipo booleano): vadimtropashko.wordpress.com/2010/09/16/…
Jeffrey Kemp,

7
@JeffreyKemp Quel blog non è sensato. Solo perché alcuni valori booleani possono essere calcolati sulla base di altri campi in una tabella, non significa che tutti i campi booleani possano essere calcolati. Ad esempio "is_trusted_customer" dove questo è vero se e solo se un essere umano decide "Mi fido di quella persona".
Jacob,

2
@JeffreyKemp Complimenti, hai appena reinventato i booleani in stile C (dove intinvece usi s). Dovremmo sicuramente tornare a quelli nel codice. Inoltre, l'argomento cade completamente a pezzi se i tipi di dati tra le colonne della tabella e le colonne dei risultati (da a SELECT) sono condivisi, poiché è assolutamente appropriato restituire un valore booleano come risultato calcolato a volte anche dato il resto dell'argomento.
jpmc26,

2
Sì. Un numero maggiore di tipi di dati come i booleani darebbe un potere espressivo più esatto: da questo punto di vista non avrò alcun argomento da parte mia. Sono solo contento che almeno abbiamo un DATEtipo - immagina di dover sempre fare i conti con le rappresentazioni di stringhe delle date :)
Jeffrey Kemp,

Risposte:


277

Non solo manca il tipo di dati booleano nell'SQL di Oracle (non PL / SQL), ma non hanno anche chiare raccomandazioni su cosa usare invece. Vedi questa discussione su asktom. Dalla raccomandazione CHAR(1) 'Y'/'N'passano a NUMBER(1) 0/1quando qualcuno sottolinea che 'Y'/'N'dipende dalla lingua inglese, mentre ad esempio i programmatori tedeschi potrebbero usare 'J'/'N'invece.

La cosa peggiore è che difendono questa stupida decisione proprio come difendono la ''=NULLstupidità.


9
1/0 è, se non ambiguo, almeno meno ambiguo.
Adam Musch,

15
Ma '' = NULL è falso! '' IS NULL è vero. :)
Jim Davis,

4
Michael-O: L'ho visto più volte. Per me è sempre 0/1, ma altri programmatori preferiscono il J / N. (Vivo in un paese di lingua tedesca)
Erich Kitzmueller,

11
@Irfy Di recente, ho visto Ne Fusato, perché ONe OFFcomincio con la stessa lettera ...
JimmyB il

7
si potrebbe sostenere che, in sostituzione di un valore booleano, "T" / "F" ha ancora più senso
Erich Kitzmueller,

55

No.

Poter usare:

IS_COOL NUMBER(1,0)

1 - true
0 - false

--- divertiti con Oracle

Oppure usa char Y / N come descritto qui


6
Preferisco char (1) perché utilizza meno spazio. Puoi verificarlo in questo modo: create table testbool (boolc char(1), booln number(1)); insert into testbool values ('Y', 1 ); select dump(boolc), dump(booln) from testbool; quel CHAR è memorizzato: Typ=96 Len=1: 89e quel NUMERO: Typ=2 Len=2: 193,2almeno in 12c, NUMERO (1) può usare 2 byte ...
phil_w

38

Secondo le risposte di Ammoq e kupa, usiamo il numero (1) con un valore predefinito di 0 e non consentiamo null.

ecco una colonna aggiunta per dimostrare:

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

Spero che questo aiuti qualcuno.


17
Si noti che è possibile memorizzare -1 anche lì. È possibile aggiungere un vincolo di controllo su quello per limitare i valori a 0 e 1.
David Aldridge

@DavidAldridge Nella logica booleana, qualsiasi numero diverso da 0 (FALSE) equivale a 1 (TRUE), quindi non importa quale numero è memorizzato, annullando la necessità di un vincolo di controllo. Aggiungere una funzione che restituisce un valore booleano da un int è banale:boolean intToBool(int in) { return (in != 0); }
Agi Hammerthief,

3
@AgiHammerthief Vero, ma se vuoi trovare righe usando un predicato nella colonna "booleana" preferirei sapere che le mie opzioni sono ColumnName = 0o ColumnName = 1, piuttosto che ColumnName = 0o ColumnName <> 0. La semantica dell'ultima non è adatta ai programmatori. Vorrei anche renderlo più semplice per Query Optimizer avendo due valori.
David Aldridge,

14

Non a livello di SQL e questo è un peccato. Ne esiste uno in PLSQL


13

No, non esiste un tipo booleano nel database Oracle, ma puoi farlo in questo modo:

È possibile inserire un vincolo di controllo su una colonna.

Se la tua tabella non ha una colonna di controllo, puoi aggiungerla:

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

Quando aggiungi un registro, per impostazione predefinita questa colonna ottiene 1.

Qui metti un segno di spunta che limita il valore della colonna, basta solo inserire 1 o 0

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

9

No, non esiste un tipo booleano, ma al posto di questo puoi 1/0 (tipo numero), o 'Y' / 'N' (tipo char), o 'true' / 'false' (tipo varchar2).



4

Un trucco per risparmiare spazio è la memorizzazione di valori booleani come Oracle CHAR , anziché NUMBER:


4
CHAR (1) e VARCHAR2 (1) sono identici nell'uso dello spazio.
Tony Andrews,

3
Come ho appreso qui docs.oracle.com/cd/E17952_01/refman-5.5-en/char.html quando raccontiamo un carattere esiste una differenza solo tra char e varchar - char usa 1 byte, ma varchar usa 1 byte per spazio vuoto + 1 byte per un carattere -> varchar (varchar2) utilizza 2 byte per 1 carattere <quando char utilizza solo 1 byte
Artem.Borysov

@ Artem.Borysov: quel manuale è per MySQL, non per il database Oracle
a_horse_with_no_name

3

Solo perché nessuno lo ha ancora menzionato: usare RAW (1) sembra anche una pratica comune.


1
raw (1) è fantastico, in quanto l'utente non può assumere ciò che è in esso, la persona che sta eseguendo la query deve capire cosa c'è nella colonna raw (1) e tradurlo in qualcosa di significativo.
Jacob,

13
<sarcasm> Sì, è così bello che non puoi scrivere codice jdbc portatile con esso. </
sarcasm

@jacob - <sarcasm> È un'idea fantastica! Dovremmo sbarazzarci di tutti gli altri tipi di dati e archiviare tutto nelle colonne RAW! Quindi NESSUNO potrebbe interpretare erroneamente i dati! </sarcasm>
Bob Jarvis - Reinstalla Monica il

Immagina se in Oracle ci fosse un modo per definire i tipi di dati in modo da poter creare un tipo bool che avvolga il tipo 'raw (1)' nominandolo booleano o booleano. Potremmo quindi definire una funzione per stampare 'vero' o 'falso' a seconda del contenuto.
Jacob,

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

Questo esempio funziona. Ho anche notato che posso lavorare solo con tipi booleani in PL / SQL. Le chiamate booleane in SQL non lo fanno e generano un errore dell'operatore relazionale non valido.
Richard Pascual,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.