Stocker la valeur booléenne dans SQLite

284

Quel est le type d'une valeur BOOL dans SQLite? Je veux stocker dans ma table des valeurs TRUE / FALSE.

Je pourrais créer une colonne INTEGER et y stocker des valeurs 0 ou 1, mais ce ne sera pas le meilleur moyen d'implémenter le type BOOL.

Y a-t-il un moyen?

Merci.

Ilya Suzdalnitski
la source
2
doublon possible de Y a
Joshua Pinter

Réponses:

365

Il n'y a pas de type de données booléen natif pour SQLite. Selon le document Datatypes :

SQLite n'a pas de classe de stockage booléenne distincte. Au lieu de cela, les valeurs booléennes sont stockées sous forme d'entiers 0 (faux) et 1 (vrai).

Lasse V. Karlsen
la source
24
"INTEGER. La valeur est un entier signé, stocké dans 1, 2, 3, 4, 6 ou 8 octets selon l'ampleur de la valeur." Je suppose que l'utilisation d'un octet pour stocker un BOOL n'est pas trop mal.
joce
2
Directement de la bouche du cheval: "SQLite n'a pas de classe de stockage booléenne distincte. Au lieu de cela, les valeurs booléennes sont stockées sous forme d'entiers 0 (faux) et 1 (vrai)".
Tobias
3
Ce qui est mieux en termes de performances! vrai / faux en tant que chaînes ou entier 0/1?
Muhammad Babar
9
@MuhammadBabar 0/1 très certainement. Les cordes sont plus lentes et prennent plus de place.
Davor
1
@joce En fait, les entiers 0 et 1 (ainsi que NULL) sont encodés directement dans la déclaration de type de données de ligne. Donc, c'est zéro octet par booléen, si vous ne comptez que le stockage de données réel, ce qui est génial. Si vous comptez la comptabilité par colonne par ligne requise par le format de fichier, tous les types de données ont un octet supplémentaire requis, ce qui n'est pas génial. :) (référence: sqlite.org/fileformat.html#record_format )
relative_random
93

Dans SQLite, le mieux que vous puissiez faire est d'utiliser les entiers 0 et 1 pour représenter faux et vrai. Vous pouvez déclarer le type de colonne comme ceci:

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

Omettez le NOT NULLsi vous souhaitez autoriser NULLen plus de 0 et 1.

L'utilisation du nom de type BOOLEANici est pour la lisibilité, pour SQLite, c'est juste un type avec une affinité NUMÉRIQUE .

Notez que les contraintes CHECK sont prises en charge depuis SQLite 3.3.0 (2006).

Voici quelques exemples INSERT qui fonctionneront: (notez comment les chaînes et les nombres à virgule flottante sont analysés comme des entiers)

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

et certains qui échoueront:

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
la source
86

Type de données booléen SQLite :
SQLite n'a pas de classe de stockage booléenne distincte. Au lieu de cela, les valeurs booléennes sont stockées sous forme d'entiers 0 (faux) et 1 (vrai).

Vous pouvez convertir un booléen en int de cette manière:

int flag = (boolValue)? 1 : 0;

Vous pouvez reconvertir int en booléen comme suit:

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

Si vous souhaitez explorer sqlite, voici un tutoriel .
J'ai donné une réponse ici . Cela fonctionne pour eux.

Muhammad Nabeel Arif
la source
13
la dernière ligne de code pourrait simplement être "Boolean flag2 = (intValue == 1)"
cja
16
Je suggèreBoolean flag2 = (intValue != 0);
Hamzeh Soboh
ou vous pouvez simplement faire booléen flag2 = (intValue> 0);
Efrain Sanjay Adhikary du
7

l'utilisation du type de données Integer avec les valeurs 0 et 1 est la plus rapide.

Logvinov Alecksey
la source
5

Suite à la réponse d'Ericwa. Les contraintes CHECK peuvent activer une colonne pseudo-booléenne en appliquant un type de données TEXT et en n'autorisant que les valeurs spécifiques à la casse TRUE ou FALSE, par exemple

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
la source
5

Mais, si vous voulez en stocker un tas, vous pouvez les déplacer par bits et les stocker tous sous la forme d'un entier, un peu comme les autorisations / modes de fichiers Unix.

Pour le mode 755 par exemple, chaque chiffre fait référence à une classe d'utilisateurs différente: propriétaire, groupe, public. Dans chaque chiffre 4 est lu, 2 est écrit, 1 est exécuté, donc 7 est tous comme le binaire 111. 5 est lu et exécuté, donc 101. Créez votre propre schéma de codage.

J'écris juste quelque chose pour stocker les données de programmation TV de Schedules Direct et j'ai les champs binaires ou oui / non: stéréo, hdtv, nouveau, ei, sous-titré, dolby, sap en espagnol, première de la saison. Donc 7 bits, ou un entier avec un maximum de 127. Un caractère vraiment.

Exemple AC de ce que je travaille maintenant. has () est une fonction qui renvoie 1 si la 2ème chaîne est dans la première. inp est la chaîne d'entrée de cette fonction. misc est un caractère non signé initialisé à 0.

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;

Je stocke donc 7 booléens dans un entier avec de la place pour plus.

Alan Corey
la source
Cette réponse est tellement réconfortante dans une perspective CS. :)
varun
2

Vous pouvez simplifier les équations ci-dessus en utilisant ce qui suit:

boolean flag = sqlInt != 0;

Si la représentation int (sqlInt) du booléen est 0 (faux), le booléen (indicateur) sera faux, sinon ce sera vrai.

Il est toujours plus agréable de travailler avec du code concis :)

The Hungry Androider
la source
-4

Une autre façon de le faire est une colonne TEXT. Convertissez ensuite la valeur booléenne entre Boolean et String avant / après avoir enregistré / lu la valeur dans la base de données.

Ex. Vous avez "boolValue = true;"

Pour chaîne:

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

Et revenons au booléen:

//convert the string back to boolean
bool Boolvalue = Convert.ToBoolean(StringValue);
Niels Schmidt
la source
6
@Craig McMahon suggère d'utiliser Integer à la place: les nombres premiers représentent vrai, les non premiers représentent faux
Berik
19
Je trouve cela très offensant, @Berik. La solution évidente consiste à restituer le mot «VRAI» ou «FAUX» sur une image, puis à l'enregistrer dans la ligne de la base de données en tant que BLOB encodé JPEG. On pourrait alors relire la valeur en utilisant un algorithme d'extraction de fonctionnalités simple.
Craig McMahon