Almacenar valor booleano en SQLite


284

¿Cuál es el tipo de un valor BOOL en SQLite? Quiero almacenar en mi tabla los valores VERDADERO / FALSO.

Podría crear una columna de INTEGER y almacenar en ella valores 0 o 1, pero no será la mejor manera de implementar el tipo BOOL.

¿Hay alguna manera?

Gracias.


Respuestas:


365

No hay un tipo de datos booleano nativo para SQLite. Según el documento Datatypes :

SQLite no tiene una clase de almacenamiento booleana separada. En cambio, los valores booleanos se almacenan como enteros 0 (falso) y 1 (verdadero).


24
"INTEGER. El valor es un entero con signo, almacenado en 1, 2, 3, 4, 6 u 8 bytes, dependiendo de la magnitud del valor". Supongo que usar 1 byte para almacenar un BOOL no es tan malo.
joce

2
Directamente de la boca del caballo: "SQLite no tiene una clase de almacenamiento booleana separada. En cambio, los valores booleanos se almacenan como enteros 0 (falso) y 1 (verdadero)".
Tobias

3
¡Cuál es mejor en términos de rendimiento! verdadero / falso como cadenas o entero 0/1?
Muhammad Babar

9
@MuhammadBabar 0/1 definitivamente. Las cuerdas son más lentas y ocupan más espacio.
Davor

1
@joce En realidad, los enteros 0 y 1 (así como NULL) se codifican directamente en la declaración de tipo de datos de fila. Entonces, es cero bytes por booleano, si solo cuenta el almacenamiento de datos real, lo cual es increíble. Sin embargo, si cuenta la contabilidad por columna por fila requerida por el formato de archivo, todos los tipos de datos tienen un byte adicional requerido, lo cual no es sorprendente. :) (referencia: sqlite.org/fileformat.html#record_format )
relativamente_

93

En SQLite, lo mejor que puede hacer es usar los enteros 0 y 1 para representar falso y verdadero. Podría declarar el tipo de columna de esta manera:

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

Omita el NOT NULLsi desea permitir NULLademás de 0 y 1.

El uso del nombre del tipo BOOLEANaquí es para facilitar la lectura, para SQLite es solo un tipo con afinidad NUMÉRICA .

Tenga en cuenta que las restricciones CHECK se admiten desde SQLite 3.3.0 (2006).

Aquí hay algunos INSERTOS de ejemplo que funcionarán: (observe cómo las cadenas y los números de coma flotante se analizan como enteros)

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

y algunos que fallarán:

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

86

Tipo de datos booleanos SQLite :
SQLite no tiene una clase de almacenamiento booleana separada. En cambio, los valores booleanos se almacenan como enteros 0 (falso) y 1 (verdadero).

Puede convertir booleano a int de esta manera:

int flag = (boolValue)? 1 : 0;

Puede convertir int de nuevo a booleano de la siguiente manera:

 // 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 desea explorar sqlite, aquí hay un tutorial .
He dado una respuesta aquí . Está funcionando para ellos.


13
la última línea de código podría ser "Boolean flag2 = (intValue == 1)"
cja

16
SugieroBoolean flag2 = (intValue != 0);
Hamzeh Soboh

o simplemente puede hacer Boolean flag2 = (intValue> 0);
Efrain Sanjay Adhikary


5

Además de la respuesta de ericwa. Las restricciones CHECK pueden habilitar una columna pseudo booleana al imponer un tipo de datos TEXT y solo permitir valores específicos de caso VERDADERO o FALSO, por ejemplo

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

5

Pero, si desea almacenar un montón de ellos, puede cambiarlos y almacenarlos todos como un int, un poco como los permisos / modos de archivo Unix.

Para el modo 755, por ejemplo, cada dígito se refiere a una clase diferente de usuarios: propietario, grupo, público. Dentro de cada dígito se lee 4, 2 se escribe, 1 se ejecuta para que 7 sea como el binario 111. 5 se lee y se ejecuta para 101. Cree su propio esquema de codificación.

Solo estoy escribiendo algo para almacenar datos de programación de TV de Schedules Direct y tengo los campos binarios o sí / no: estéreo, hdtv, nuevo, ei, subtítulos, dolby, sap en español, estreno de temporada. Entonces 7 bits, o un número entero con un máximo de 127. Un personaje realmente.

Ejemplo de AC de lo que estoy trabajando ahora. has () es una función que devuelve 1 si la segunda cadena está en la primera. inp es la cadena de entrada a esta función. misc es un carácter sin signo inicializado a 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;

Así que estoy almacenando 7 booleanos en un entero con espacio para más.


Esta respuesta es tan conmovedora en una perspectiva CS. :)
varun

2

Puede simplificar las ecuaciones anteriores utilizando lo siguiente:

boolean flag = sqlInt != 0;

Si la representación int (sqlInt) del booleano es 0 (falso), el booleano (bandera) será falso, de lo contrario será verdadero.

El código conciso siempre es más agradable para trabajar :)


-4

Otra forma de hacerlo es una columna TEXTO. Y luego convierta el valor booleano entre Boolean y String antes / después de guardar / leer el valor de la base de datos.

Ex. Tienes "boolValue = true;"

Encadenar:

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

Y de vuelta a booleano:

//convert the string back to boolean
bool Boolvalue = Convert.ToBoolean(StringValue);

66
@Craig McMahon sugiere usar Integer en su lugar: los números primos representan verdadero, los no primos representan falso
Berik

18
Me parece muy ofensivo, @Berik. La solución obvia es representar la palabra "VERDADERO" o "FALSO" en una imagen y luego guardarla en la fila de la base de datos como un BLOB codificado en JPEG. Entonces se podría leer el valor de nuevo utilizando un algoritmo de extracción de características simple.
Craig McMahon
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.