Speichern Sie den booleschen Wert in SQLite

284

Was ist der Typ für einen BOOL-Wert in SQLite? Ich möchte TRUE / FALSE-Werte in meiner Tabelle speichern.

Ich könnte eine Spalte von INTEGER erstellen und darin Werte 0 oder 1 speichern, aber es ist nicht der beste Weg, den BOOL-Typ zu implementieren.

Gibt es einen Weg?

Vielen Dank.

Ilya Suzdalnitski
quelle
2
Mögliches Duplikat von Gibt es in SQLite ein boolesches Literal?
Joshua Pinter

Antworten:

365

Es gibt keinen nativen booleschen Datentyp für SQLite. Gemäß dem Datentyp-Dokument :

SQLite verfügt nicht über eine separate boolesche Speicherklasse. Stattdessen werden Boolesche Werte als Ganzzahlen 0 (falsch) und 1 (wahr) gespeichert.

Lasse V. Karlsen
quelle
24
"INTEGER. Der Wert ist eine vorzeichenbehaftete Ganzzahl, die je nach Größe des Werts in 1, 2, 3, 4, 6 oder 8 Bytes gespeichert wird." Ich denke, 1 Byte zum Speichern eines BOOL zu verwenden, ist nicht schlecht.
Joce
2
Direkt aus dem Maul des Pferdes: "SQLite verfügt nicht über eine separate Boolesche Speicherklasse. Stattdessen werden Boolesche Werte als Ganzzahlen 0 (falsch) und 1 (wahr) gespeichert."
Tobias
3
Welches ist besser in Bezug auf die Leistung! wahr / falsch als Zeichenfolgen oder 0/1 Ganzzahl?
Muhammad Babar
9
@ MuhammadBabar 0/1 auf jeden Fall. Saiten sind langsamer und nehmen mehr Platz ein.
Davor
1
@joce Tatsächlich werden die Ganzzahlen 0 und 1 (sowie NULL) direkt in der Zeilendatentypdeklaration codiert. Es sind also null Bytes pro Boolescher Wert, wenn Sie nur den tatsächlichen Datenspeicher zählen, was fantastisch ist. Wenn Sie jedoch die für das Dateiformat erforderliche Buchhaltung pro Spalte und Zeile zählen, ist für alle Datentypen ein zusätzliches Byte erforderlich, was nicht besonders beeindruckend ist. :) (Referenz: sqlite.org/fileformat.html#record_format )
relativ
93

In SQLite können Sie am besten die Ganzzahlen 0 und 1 verwenden, um false und true darzustellen. Sie können den Spaltentyp folgendermaßen deklarieren:

CREATE TABLE foo(mycolumn BOOLEAN NOT NULL CHECK (mycolumn IN (0,1)));

Lassen Sie das weg, NOT NULLwenn Sie NULLzusätzlich zu 0 und 1 zulassen möchten .

Die Verwendung des Typnamens dientBOOLEAN hier der Lesbarkeit. Für SQLite ist dies nur ein Typ mit NUMERISCHER Affinität .

Beachten Sie, dass CHECK-Einschränkungen seit SQLite 3.3.0 (2006) unterstützt werden.

Hier sind einige Beispiele für INSERTs, die funktionieren: (Beachten Sie, wie Zeichenfolgen und Gleitkommazahlen als Ganzzahlen analysiert werden.)

sqlite> INSERT INTO foo VALUES(0);
sqlite> INSERT INTO foo VALUES(1);
sqlite> INSERT INTO foo VALUES(0.0);
sqlite> INSERT INTO foo VALUES(1.0);
sqlite> INSERT INTO foo VALUES("0.0");
sqlite> INSERT INTO foo VALUES("1.0");
sqlite> select mycolumn, typeof(mycolumn) from foo;
0|integer
1|integer
0|integer
1|integer
0|integer
1|integer

und einige, die scheitern werden:

sqlite> INSERT INTO foo VALUES("-1");
Error: constraint failed
sqlite> INSERT INTO foo VALUES(0.24);
Error: constraint failed
sqlite> INSERT INTO foo VALUES(100);
Error: constraint failed
sqlite> INSERT INTO foo VALUES(NULL);
Error: foo.mycolumn may not be NULL
sqlite> INSERT INTO foo VALUES("true");
Error: constraint failed
sqlite> INSERT INTO foo VALUES("false");
Error: constraint failed
Ericwa
quelle
86

Boolescher SQLite- Datentyp:
SQLite verfügt nicht über eine separate Boolesche Speicherklasse. Stattdessen werden Boolesche Werte als Ganzzahlen 0 (falsch) und 1 (wahr) gespeichert.

Sie können Boolesche Werte auf folgende Weise in int konvertieren:

int flag = (boolValue)? 1 : 0;

Sie können int wie folgt zurück in boolean konvertieren:

 // Select COLUMN_NAME  values from db. 
 // This will be integer value, you can convert this int value back to Boolean as follows
Boolean flag2 = (intValue == 1)? true : false;

Wenn Sie SQLite erkunden möchten, finden Sie hier ein Tutorial .
Ich habe eine Antwort gegeben hier . Es funktioniert für sie.

Muhammad Nabeel Arif
quelle
13
Die letzte Codezeile könnte einfach "Boolean flag2 = (intValue == 1)" sein
cja
16
Ich schlage vorBoolean flag2 = (intValue != 0);
Hamzeh Soboh
oder Sie können einfach Boolean flag2 = (intValue> 0) ausführen;
Efrain Sanjay Adhikary
7

Die Verwendung des Datentyps Integer mit den Werten 0 und 1 ist am schnellsten.

Logvinov Alecksey
quelle
5

Weiter zu Ericas Antwort. CHECK-Einschränkungen können eine pseudo-boolesche Spalte aktivieren, indem ein TEXT-Datentyp erzwungen wird und nur fallspezifische TRUE- oder FALSE-Werte zugelassen werden, z

CREATE TABLE IF NOT EXISTS "boolean_test"
(
    "id" INTEGER PRIMARY KEY AUTOINCREMENT
,   "boolean" TEXT NOT NULL 
        CHECK( typeof("boolean") = "text" AND
               "boolean" IN ("TRUE","FALSE")
        )
);

INSERT INTO "boolean_test" ("boolean") VALUES ("TRUE");
INSERT INTO "boolean_test" ("boolean") VALUES ("FALSE");
INSERT INTO "boolean_test" ("boolean") VALUES ("TEST");

Error: CHECK constraint failed: boolean_test

INSERT INTO "boolean_test" ("boolean") VALUES ("true");

Error: CHECK constraint failed: boolean_test

INSERT INTO "boolean_test" ("boolean") VALUES ("false");

Error: CHECK constraint failed: boolean_test

INSERT INTO "boolean_test" ("boolean") VALUES (1);

Error: CHECK constraint failed: boolean_test

select * from boolean_test;

id  boolean
1   TRUE
2   FALSE
Martin Hurford
quelle
5

Wenn Sie jedoch eine Reihe von ihnen speichern möchten, können Sie sie bitverschieben und alle als ein Int speichern, ähnlich wie bei Unix-Dateiberechtigungen / -Modi.

Im Modus 755 bezieht sich beispielsweise jede Ziffer auf eine andere Benutzerklasse: Eigentümer, Gruppe, Öffentlich. Innerhalb jeder Ziffer wird 4 gelesen, 2 wird geschrieben, 1 wird ausgeführt, so dass 7 alle wie Binär 111 sind. 5 wird gelesen und ausgeführt, also 101. Erstellen Sie Ihr eigenes Codierungsschema.

Ich schreibe nur etwas zum Speichern von TV-Programmdaten aus Schedules Direct und habe die binären oder Ja / Nein-Felder: Stereo, HDTV, Neu, Ei, Untertitel, Dolby, SAP auf Spanisch, Saisonpremiere. Also 7 Bits oder eine ganze Zahl mit maximal 127. Ein Zeichen wirklich.

Ein AC-Beispiel von dem, woran ich gerade arbeite. has () ist eine Funktion, die 1 zurückgibt, wenn sich die 2. Zeichenfolge in der ersten befindet. inp ist die Eingabezeichenfolge für diese Funktion. misc ist ein vorzeichenloses Zeichen, das auf 0 initialisiert ist.

if (has(inp,"sap='Spanish'") > 0)
  misc += 1;
if (has(inp,"stereo='true'") > 0)
  misc +=2;
if (has(inp,"ei='true'") > 0)
  misc +=4;
if (has(inp,"closeCaptioned='true'") > 0)
  misc += 8;
if (has(inp,"dolby=") > 0)
  misc += 16;
if (has(inp,"new='true'") > 0)
  misc += 32;
if (has(inp,"premier_finale='") > 0)
  misc += 64;
if (has(inp,"hdtv='true'") > 0)
  misc += 128;

Also speichere ich 7 Boolesche Werte in einer ganzen Zahl mit Platz für mehr.

Alan Corey
quelle
Diese Antwort ist aus CS-Sicht so herzerwärmend. :)
Varun
2

Sie können die obigen Gleichungen folgendermaßen vereinfachen:

boolean flag = sqlInt != 0;

Wenn die int-Darstellung (sqlInt) des Booleschen Werts 0 (falsch) ist, ist der Boolesche Wert (Flag) falsch, andernfalls ist er wahr.

Prägnanter Code ist immer besser zu bearbeiten :)

Der hungrige Androider
quelle
-4

Eine andere Möglichkeit ist eine TEXT-Spalte. Konvertieren Sie dann den booleschen Wert zwischen Booleschem Wert und String, bevor / nachdem Sie den Wert aus der Datenbank gespeichert / gelesen haben.

Ex. Du hast "boolValue = true;"

Zu String:

//convert to the string "TRUE"
string StringValue = boolValue.ToString;  

Und zurück zum Booleschen:

//convert the string back to boolean
bool Boolvalue = Convert.ToBoolean(StringValue);
Niels Schmidt
quelle
6
@Craig McMahon schlägt vor, stattdessen Integer zu verwenden: Primzahlen stehen für wahr, Nicht-Primzahlen für falsch
Berik
18
Ich finde das sehr beleidigend, @Berik. Die naheliegende Lösung besteht darin, das Wort "TRUE" oder "FALSE" auf einem Bild zu rendern und dieses dann in der Datenbankzeile als JPEG-codiertes BLOB zu speichern. Man könnte dann den Wert unter Verwendung eines einfachen Merkmalsextraktionsalgorithmus zurücklesen.
Craig McMahon