Armazenar valor booleano no SQLite

284

Qual é o tipo de um valor BOOL no SQLite? Quero armazenar na minha tabela valores TRUE / FALSE.

Eu poderia criar uma coluna de INTEGER e armazenar os valores 0 ou 1, mas não será a melhor maneira de implementar o tipo BOOL.

Há algum jeito?

Obrigado.

Ilya Suzdalnitski
fonte
2
possível duplicata de Existe um literal booleano no SQLite?
Joshua Pinter

Respostas:

365

Não há tipo de dados booleano nativo para SQLite. De acordo com o documento Tipos de dados :

O SQLite não possui uma classe de armazenamento booleana separada. Em vez disso, os valores booleanos são armazenados como números inteiros 0 (false) e 1 (true).

Lasse V. Karlsen
fonte
24
"INTEGER. O valor é um número inteiro assinado, armazenado em 1, 2, 3, 4, 6 ou 8 bytes, dependendo da magnitude do valor." Eu acho que usar 1 byte para armazenar um BOOL não é tão ruim.
2113 joce #
2
Diretamente da boca do cavalo: "O SQLite não possui uma classe de armazenamento booleana separada. Em vez disso, os valores booleanos são armazenados como números inteiros 0 (false) e 1 (true)."
Tobias
3
Qual é o melhor em termos de desempenho! verdadeiro / falso como cadeias de caracteres ou inteiro 0/1?
Muhammad Babar
9
@MuhammadBabar 0/1 definitivamente. As strings são mais lentas e ocupam mais espaço.
Davor
1
@joce Na verdade, os números inteiros 0 e 1 (assim como NULL) são codificados diretamente na declaração do tipo de dados da linha. Portanto, são zero bytes por booleano, se você contar apenas o armazenamento de dados real, o que é incrível. Se você contar a contabilidade por coluna por linha exigida pelo formato do arquivo, todos os tipos de dados terão um byte extra necessário, o que não é impressionante. :) (referência: sqlite.org/fileformat.html#record_format )
relativamente_random
93

No SQLite, o melhor que você pode fazer é usar os números inteiros 0 e 1 para representar falso e verdadeiro. Você pode declarar o tipo de coluna assim:

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

Omita o NOT NULLque você deseja permitir NULL, além de 0 e 1.

O uso do nome do tipo BOOLEANaqui é para facilitar a leitura, para o SQLite é apenas um tipo com afinidade NUMÉRICA .

Observe que as restrições CHECK são suportadas desde o SQLite 3.3.0 (2006).

Aqui estão alguns exemplos de INSERTs que funcionarão: (observe como seqüências de caracteres e números de ponto flutuante são analisados ​​como números inteiros)

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

e alguns que falharão:

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
fonte
86

Tipo de dados booleano do SQLite : O
SQLite não possui uma classe de armazenamento booleana separada. Em vez disso, os valores booleanos são armazenados como números inteiros 0 (false) e 1 (true).

Você pode converter booleano em int desta maneira:

int flag = (boolValue)? 1 : 0;

Você pode converter int novamente em booleano da seguinte maneira:

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

Se você deseja explorar o sqlite, aqui está um tutorial .
Eu dei uma resposta aqui . Está trabalhando para eles.

Muhammad Nabeel Arif
fonte
13
A linha final do código pode ser apenas "booleano flag2 = (intValue == 1)"
cja
16
Eu sugiroBoolean flag2 = (intValue != 0);
Hamzeh Soboh
ou você pode simplesmente fazer Boolean flag2 = (intValue> 0);
Efrain Sanjay Adhikary
7

usar o tipo de dados Inteiro com os valores 0 e 1 é o mais rápido.

Logvinov Alecksey
fonte
5

Além da resposta de ericwa. As restrições CHECK podem ativar uma coluna pseudo-booleana aplicando um tipo de dados TEXT e permitindo apenas valores específicos de caso TRUE ou FALSE, por exemplo

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
fonte
5

Mas, se você deseja armazenar vários deles, pode alterá-los e armazená-los como um int, como as permissões / modos de arquivo unix.

Para o modo 755, por exemplo, cada dígito refere-se a uma classe diferente de usuários: proprietário, grupo, público. Dentro de cada dígito 4 é lido, 2 é gravado, 1 é executado e 7 são todos iguais ao 111 binário. 5 são lidos e executados assim 101. Crie seu próprio esquema de codificação.

Estou apenas escrevendo algo para armazenar dados de programação de TV do Schedules Direct e tenho os campos binários ou sim / não: estéreo, hdtv, novo, ei, legendas ocultas, dolby, sap em espanhol, estréia da temporada. Então, 7 bits ou um número inteiro com no máximo 127. Um caractere realmente.

Um exemplo do que estou trabalhando agora. has () é uma função que retorna 1 se a segunda string estiver na primeira. inp é a string de entrada para esta função. misc é um caracter não assinado inicializado como 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;

Então, eu estou armazenando 7 booleanos em um inteiro com espaço para mais.

Alan Corey
fonte
Essa resposta é muito emocionante na perspectiva do CS. :)
varun
2

Você pode simplificar as equações acima usando o seguinte:

boolean flag = sqlInt != 0;

Se a representação int (sqlInt) do booleano for 0 (false), o booleano (flag) será falso, caso contrário será verdadeiro.

Código conciso é sempre melhor trabalhar com :)

The Hungry Androider
fonte
-4

Outra maneira de fazer isso é uma coluna TEXT. E então converta o valor booleano entre Booleano e String antes / depois de salvar / ler o valor do banco de dados.

Ex. Você tem "boolValue = true;"

Para sequenciar:

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

E voltando ao booleano:

//convert the string back to boolean
bool Boolvalue = Convert.ToBoolean(StringValue);
Niels Schmidt
fonte
6
@ Craig McMahon sugere usar Integer em vez disso: números primos representam verdadeiros, não-primes representam falsa
Berik
18
Acho isso altamente ofensivo, @Berik. A solução óbvia é renderizar a palavra "VERDADEIRO" ou "FALSO" em uma imagem e salvá-la na linha do banco de dados como um BLOB codificado em JPEG. Pode-se então ler o valor de volta usando um algoritmo simples de extração de recursos.
Craig McMahon