Gibt es einen booleschen Typ in Oracle-Datenbanken?

249

Gibt es in Oracle-Datenbanken einen booleschen Typ, der dem BITDatentyp in MS SQL Server ähnelt ?

Peder
quelle
7
Leider unterstützt Oracle den ANSI SQL: 1999-Standard ( en.wikipedia.org/wiki/SQL:1999 ) bei seiner Einführung nicht vollständig .
Jeffrey Kemp
2
Alternativer Standpunkt (warum SQL keinen booleschen Typ haben sollte): vadimtropashko.wordpress.com/2010/09/16/…
Jeffrey Kemp
7
@ JeffreyKemp Dieser Blog ist unsinnig. Nur weil einige Boolesche Werte basierend auf anderen Feldern in einer Tabelle berechnet werden können, bedeutet dies nicht, dass alle Booleschen Felder berechnet werden können. Zum Beispiel "is_trusted_customer", wo dies genau dann zutrifft, wenn ein Mensch entscheidet: "Ich vertraue dieser Person."
Jacob
2
@ JeffreyKemp Herzlichen Glückwunsch, Sie haben gerade die Booleschen Werte im C-Stil neu erfunden (wo Sie stattdessen ints verwenden). Wir sollten auf jeden Fall zu denen im Code zurückkehren. Darüber hinaus fällt das Argument vollständig auseinander, wenn die Datentypen zwischen Tabellenspalten und Ergebnisspalten (von a SELECT) gemeinsam genutzt werden, da es absolut angemessen ist, einen Booleschen Wert als berechnetes Ergebnis zurückzugeben, manchmal sogar angesichts des restlichen Arguments.
jpmc26
2
Ja. Mehr Datentypen wie Boolesche Werte würden eine genauere Ausdruckskraft ergeben - Sie werden in dieser Hinsicht kein Argument von mir erhalten. Ich bin nur froh, dass wir zumindest einen DATETyp haben - stellen Sie sich vor, Sie müssen sich die ganze Zeit mit String-Darstellungen von Daten befassen :)
Jeffrey Kemp

Antworten:

277

Der boolesche Datentyp fehlt nicht nur in Oracle SQL (nicht PL / SQL), sondern sie haben auch keine klare Empfehlung, was stattdessen verwendet werden soll. Siehe diesen Thread auf asktom. Von der Empfehlung CHAR(1) 'Y'/'N'wechseln sie zu, NUMBER(1) 0/1wenn jemand darauf hinweist, dass dies 'Y'/'N'von der englischen Sprache abhängt, während z. B. deutsche Programmierer 'J'/'N'stattdessen verwenden könnten .

Das Schlimmste ist, dass sie diese dumme Entscheidung genauso verteidigen wie die ''=NULLDummheit.

Erich Kitzmüller
quelle
9
1/0 ist, wenn nicht mehrdeutig, zumindest weniger mehrdeutig.
Adam Musch
15
Aber '' = NULL ist falsch! '' IS NULL ist wahr. :)
Jim Davis
4
Michael-O: Das habe ich schon mehrmals gesehen. Für mich ist es immer 0/1, aber andere Programmierer bevorzugen J / N. (Ich lebe in einem deutschsprachigen Land)
Erich Kitzmüller
11
@ Irfy Vor kurzem habe ich gesehen Nund Fverwendet, weil ONund OFFbeginnen mit dem gleichen Buchstaben ...
JimmyB
7
man könnte argumentieren, dass 'T' / 'F' als Ersatz für einen Booleschen noch sinnvoller ist
Erich Kitzmüller
55

Nee.

Kann benutzen:

IS_COOL NUMBER(1,0)

1 - true
0 - false

--- genieße Oracle

Oder verwenden Sie char Y / N wie hier beschrieben

Bohdan
quelle
6
Ich bevorzuge char (1), weil es weniger Platz benötigt. Sie können dies folgendermaßen überprüfen: create table testbool (boolc char(1), booln number(1)); insert into testbool values ('Y', 1 ); select dump(boolc), dump(booln) from testbool; Das CHAR wird gespeichert: Typ=96 Len=1: 89und das NUMBER: Typ=2 Len=2: 193,2Zumindest in 12c kann NUMBER (1) 2 Bytes verwenden ...
phil_w
38

Gemäß den Antworten von Ammoq und kupa verwenden wir die Nummer (1) mit dem Standardwert 0 und lassen keine Nullen zu.

Hier ist eine Spalte zum Hinzufügen, um zu demonstrieren:

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

Hoffe das hilft jemandem.

Alex Stephens
quelle
17
Beachten Sie, dass Sie dort auch -1 speichern können. Sie können eine Prüfbedingung hinzufügen, um die Werte auf 0 und 1 zu begrenzen.
David Aldridge
@DavidAldridge In der Booleschen Logik entspricht jede Zahl, die nicht 0 (FALSE) ist, 1 (TRUE). Es spielt also keine Rolle, welche Zahl gespeichert ist, sodass keine Prüfbedingung erforderlich ist. Das Hinzufügen einer Funktion, die einen Booleschen Wert von einem int zurückgibt, ist trivial:boolean intToBool(int in) { return (in != 0); }
Agi Hammerthief
3
@AgiHammerthief Stimmt, aber wenn Sie Zeilen mit einem Prädikat in der Spalte "Boolean" suchen möchten, würde ich lieber wissen, dass meine Optionen ColumnName = 0oder sind ColumnName = 1, anstatt ColumnName = 0oder ColumnName <> 0. Die Semantik des letzten ist nicht programmiererfreundlich. Ich möchte es auch für den Abfrageoptimierer einfacher halten, indem ich zwei Werte habe.
David Aldridge
14

Nicht auf SQL-Ebene und das ist schade. Es gibt jedoch eine in PLSQL

vc 74
quelle
13

Nein, es gibt keinen booleschen Typ in Oracle Database, aber Sie können dies folgendermaßen tun:

Sie können einer Spalte eine Prüfbedingung hinzufügen.

Wenn Ihre Tabelle keine Prüfspalte enthält, können Sie sie hinzufügen:

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

Wenn Sie ein Register hinzufügen, erhält diese Spalte standardmäßig 1.

Hier setzen Sie ein Häkchen, das den Spaltenwert begrenzt, nur 1 oder 0

ALTER TABLE table_name ADD
CONSTRAINT name_constraint 
column_name_check (ONOFF in ( '1', '0' ));
Roberto Góes
quelle
9

Nein, es gibt keinen booleschen Typ, aber stattdessen können Sie 1/0 (Typennummer) oder 'Y' / 'N' (Typ char) oder 'true' / 'false' (Typ varchar2) verwenden.

kupa
quelle
4

Ein gängiger platzsparender Trick ist das Speichern von Booleschen Werten als Oracle CHAR anstelle von NUMBER:

Pranay Rana
quelle
4
CHAR (1) und VARCHAR2 (1) sind in der Raumnutzung identisch.
Tony Andrews
3
Wie ich hier erfahren habe, gibt es bei docs.oracle.com/cd/E17952_01/refman-5.5-en/char.html nur einen Unterschied zwischen char und varchar - char verwendet 1 Byte, aber varchar verwendet 1 Byte für leeren Raum + 1 Byte für ein Zeichen -> varchar (varchar2) verwendet 2 Bytes für 1 Zeichen <wenn char nur 1 Byte verwendet
Artem.Borysov
@ Artem.Borysov: Dieses Handbuch ist für MySQL, nicht für die Oracle-Datenbank
a_horse_with_no_name
3

Nur weil es noch niemand erwähnt hat: Die Verwendung von RAW (1) scheint ebenfalls gängige Praxis zu sein.

Filburt
quelle
1
raw (1) ist insofern großartig, als der Benutzer nicht annehmen kann, was darin enthalten ist. Die Person, die die Abfrage ausführt, muss verstehen, was in der raw (1) -Spalte steht, und es in etwas Sinnvolles übersetzen.
Jacob
13
<Sarkasmus> Ja, es ist so großartig, dass Sie keinen tragbaren JDBC-Code damit schreiben können. </ Sarkasmus>
Chubbsondubs
@jacob - <Sarkasmus> Das ist eine erstaunliche Idee! Wir sollten alle anderen Datentypen loswerden und alles in RAW-Spalten speichern! Dann könnte NIEMAND die Daten willkürlich falsch interpretieren! </ Sarkasmus>
Bob Jarvis - Reinstate Monica
Stellen Sie sich vor, es gäbe eine Möglichkeit in Oracle, Datentypen zu definieren, damit wir einen Bool-Typ erstellen können, der den Typ 'raw (1)' umschließt und ihn bool oder boolean nennt. Wir könnten dann eine Funktion definieren, um je nach Inhalt 'wahr' oder 'falsch' zu drucken.
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;
zloctb
quelle
Dieses Beispiel funktioniert. Mir ist auch aufgefallen, dass ich nur mit booleschen Typen in PL / SQL arbeiten kann. Boolesche Aufrufe in SQL funktionieren nicht und führen zu einem ungültigen Vergleichsoperatorfehler.
Richard Pascual