Memorizza il valore booleano in SQLite


284

Qual è il tipo per un valore BOOL in SQLite? Voglio memorizzare nella mia tabella i valori VERO / FALSO.

Potrei creare una colonna di INTEGER e memorizzare in esso valori 0 o 1, ma non sarà il modo migliore per implementare il tipo BOOL.

C'è un modo?

Grazie.


Risposte:


365

Non esiste un tipo di dati booleano nativo per SQLite. Per il documento Tipi di dati :

SQLite non ha una classe di archiviazione booleana separata. Invece, i valori booleani sono memorizzati come numeri interi 0 (falso) e 1 (vero).


24
"INTEGER. Il valore è un numero intero con segno, memorizzato in 1, 2, 3, 4, 6 o 8 byte a seconda della grandezza del valore." Immagino che usare 1 byte per memorizzare un BOOL non sia poi così male.
joce

2
Direttamente dalla bocca del cavallo: "SQLite non ha una classe di archiviazione booleana separata. Invece, i valori booleani sono memorizzati come numeri interi 0 (falso) e 1 (vero)."
Tobias,

3
Quale è meglio in termini di prestazioni! vero / falso come stringhe o intero 0/1?
Muhammad Babar,

9
@MuhammadBabar 0/1 sicuramente. Le stringhe sono più lente e occupano più spazio.
Assapora il

1
@joce In realtà, gli interi 0 e 1 (così come NULL) sono codificati direttamente nella dichiarazione del tipo di dati di riga. Quindi è zero byte per booleano, se si contano solo l'archiviazione effettiva dei dati, il che è fantastico. Se conteggi la contabilità per colonna per riga richiesta dal formato del file, tuttavia, tutti i tipi di dati richiedono un byte aggiuntivo, il che non è eccezionale. :) (riferimento: sqlite.org/fileformat.html#record_format )
relativamente_

93

In SQLite il meglio che puoi fare è usare gli interi 0 e 1 per rappresentare falso e vero. È possibile dichiarare il tipo di colonna in questo modo:

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

Omettere NOT NULLse si desidera consentire NULLoltre a 0 e 1.

L'uso del nome del tipo BOOLEANqui è per leggibilità, per SQLite è solo un tipo con affinità NUMERICA .

Si noti che i vincoli CHECK sono supportati da SQLite 3.3.0 (2006).

Ecco alcuni INSERT di esempio che funzioneranno: (nota come stringhe e numeri in virgola mobile vengono analizzati come numeri interi)

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 alcuni che falliranno:

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 dati booleano SQLite :
SQLite non ha una classe di archiviazione booleana separata. Invece, i valori booleani sono memorizzati come numeri interi 0 (falso) e 1 (vero).

Puoi convertire booleano in int in questo modo:

int flag = (boolValue)? 1 : 0;

È possibile riconvertire int in booleano come segue:

 // 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 vuoi esplorare sqlite, ecco un tutorial .
Ho dato una risposta qui . Funziona per loro.


13
la riga finale del codice potrebbe essere "Boolean flag2 = (intValue == 1)"
cja

16
SuggeriscoBoolean flag2 = (intValue != 0);
Hamzeh Soboh il

oppure puoi semplicemente fare booleano flag2 = (intValue> 0);
Efrain Sanjay Adhikary,


5

Oltre alla risposta di ericwa. I vincoli CHECK possono abilitare una colonna pseudo booleana applicando un tipo di dati TEXT e consentendo solo valori TRUE o FALSE specifici del caso, ad es.

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

Ma, se si desidera memorizzarne un po ', è possibile spostarli un po' e memorizzarli tutti come un unico int, un po 'come le autorizzazioni / modalità del file unix.

Ad esempio, per la modalità 755, ogni cifra si riferisce a una diversa classe di utenti: proprietario, gruppo, pubblico. All'interno di ogni cifra 4 viene letto, 2 è scritto, 1 è eseguito, quindi 7 sono tutti come il binario 111. 5 è letto ed eseguito così 101. Crea il tuo schema di codifica.

Sto solo scrivendo qualcosa per memorizzare i dati dei programmi TV da Schedules Direct e ho i campi binari o sì / no: stereo, hdtv, nuovo, ei, sottotitoli, dolby, sap in spagnolo, premiere di stagione. Quindi 7 bit, o un numero intero con un massimo di 127. Un carattere davvero.

Esempio AC da quello su cui sto lavorando ora. has () è una funzione che restituisce 1 se la seconda stringa è nella prima. inp è la stringa di input per questa funzione. misc è un carattere senza segno inizializzato su 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;

Quindi sto memorizzando 7 booleani in un intero con spazio per altro.


Questa risposta è così commovente in una prospettiva CS. :)
varun,

2

È possibile semplificare le equazioni precedenti usando quanto segue:

boolean flag = sqlInt != 0;

Se la rappresentazione int (sqlInt) del booleano è 0 (falso), il booleano (flag) sarà falso, altrimenti sarà vero.

Il codice conciso è sempre più bello con cui lavorare :)


-4

Un altro modo per farlo è una colonna TEXT. Quindi converti il ​​valore booleano tra Booleano e String prima / dopo aver salvato / letto il valore dal database.

Ex. Hai"boolValue = true; "

Accordare:

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

E torniamo al booleano:

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

6
@Craig McMahon suggerisce di usare Integer invece: i numeri primi rappresentano il vero, i non primi rappresentano il falso
Berik,

19
Lo trovo altamente offensivo, @Berik. La soluzione ovvia è rendere la parola "TRUE" o "FALSE" su un'immagine e salvarla nella riga del database come BLOB con codifica JPEG. Si potrebbe quindi rileggere il valore usando un semplice algoritmo di estrazione delle caratteristiche.
Craig McMahon,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.