Przechowuj wartość logiczną w SQLite

284

Jaki jest typ wartości BOOL w SQLite? Chcę przechowywać w mojej tabeli wartości PRAWDA / FAŁSZ.

Mógłbym utworzyć kolumnę INTEGER i zapisać w niej wartości 0 lub 1, ale nie będzie to najlepszy sposób na implementację typu BOOL.

Czy jest jakiś sposób?

Dzięki.

Ilya Suzdalnitski
źródło
2
możliwy duplikat Czy w SQLite istnieje literał boolowski?
Joshua Pinter

Odpowiedzi:

365

Nie ma natywnego typu danych logicznych dla SQLite. Zgodnie z dokumentem Datatypes :

SQLite nie ma osobnej logicznej klasy pamięci. Zamiast tego wartości logiczne są przechowywane jako liczby całkowite 0 (fałsz) i 1 (prawda).

Lasse V. Karlsen
źródło
24
„INTEGER. Wartość jest liczbą całkowitą ze znakiem, przechowywaną w 1, 2, 3, 4, 6 lub 8 bajtach w zależności od wielkości wartości.” Myślę, że użycie 1 bajtu do przechowywania BOOL nie jest takie złe.
joce
2
Prosto z ust Konia: „SQLite nie ma osobnej logicznej klasy pamięci. Zamiast tego wartości logiczne są przechowywane jako liczby całkowite 0 (fałsz) i 1 (prawda).”
Tobias
3
Co jest lepsze pod względem wydajności! prawda / fałsz jako ciągi lub liczba całkowita 0/1?
Muhammad Babar,
9
@MuhammadBabar 0/1 zdecydowanie. Struny są wolniejsze i zajmują więcej miejsca.
Davor
1
@ joce W rzeczywistości liczby całkowite 0 i 1 (a także NULL) są kodowane bezpośrednio w deklaracji typu danych wiersza. Więc to zero bajtów na boolean, jeśli liczyć tylko rzeczywiste miejsce do przechowywania danych, co jest niesamowite. Jeśli jednak policzymy księgowość na kolumnę na wiersz wymaganą przez format pliku, wszystkie typy danych wymagają dodatkowego bajtu, co nie jest niesamowite. :) (odniesienie: sqlite.org/fileformat.html#record_format )
stosunkowo_losowy
93

W SQLite najlepsze, co możesz zrobić, to użyć liczb całkowitych 0 i 1 do przedstawienia wartości false i true. Możesz zadeklarować typ kolumny w następujący sposób:

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

Pomiń, NOT NULLjeśli chcesz zezwolić NULLoprócz 0 i 1.

Użycie BOOLEANtutaj nazwy typu służy do czytelności, dla SQLite jest to po prostu typ z powinowactwem NUMERYCZNYM .

Zauważ, że ograniczenia CHECK są obsługiwane od SQLite 3.3.0 (2006).

Oto kilka przykładów WSTAWEK, które będą działać: (zwróć uwagę na to, jak ciągi i liczby zmiennoprzecinkowe są analizowane jako liczby całkowite)

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

i niektóre, które zawiodą:

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
źródło
86

SQLite Boolean Datatype:
SQLite nie ma oddzielnej logicznej klasy pamięci. Zamiast tego wartości logiczne są przechowywane jako liczby całkowite 0 (fałsz) i 1 (prawda).

Możesz przekonwertować wartość logiczną na int w następujący sposób:

int flag = (boolValue)? 1 : 0;

Możesz przekonwertować int z powrotem na boolean w następujący sposób:

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

Jeśli chcesz poznać sqlite, oto samouczek .
Podałem tutaj jedną odpowiedź . To dla nich działa.

Muhammad Nabeel Arif
źródło
13
ostatnim wierszem kodu może być po prostu „Boolean flag2 = (intValue == 1)”
cja
16
SugerujęBoolean flag2 = (intValue != 0);
Hamzeh Soboh,
lub możesz po prostu zrobić Boolean flag2 = (intValue> 0);
Efrain Sanjay Adhikary,
7

użycie typu danych Integer z wartościami 0 i 1 jest najszybsze.

Logvinov Alecksey
źródło
5

W nawiązaniu do odpowiedzi Ericwy. Ograniczenia CHECK mogą włączyć pseudo-boolowską kolumnę poprzez wymuszenie typu danych TEKST i dopuszczenie tylko wartości PRAWDA lub FAŁSZ specyficznych dla sprawy, np.

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
źródło
5

Ale jeśli chcesz przechowywać kilka z nich, możesz je przesunąć bitowo i zapisać je jako jedną int, trochę jak uprawnienia / tryby plików unixowych.

Na przykład w trybie 755 każda cyfra odnosi się do innej klasy użytkowników: właściciela, grupy, publicznej. W obrębie każdej cyfry 4 jest odczytywane, 2 jest zapisywane, 1 jest wykonywane, więc 7 to wszystkie jak binarne 111. 5 jest czytane i wykonywane tak 101. Stwórz swój własny schemat kodowania.

Właśnie piszę coś do przechowywania danych harmonogramu TV z Schedules Direct i mam pola binarne lub tak / nie: stereo, hdtv, nowy, ei, blisko podpisu, dolby, SAP w języku hiszpańskim, premiera sezonu. Więc 7 bitów lub liczba całkowita z maksymalnie 127. Naprawdę jeden znak.

Przykład AC z tego, nad czym teraz pracuję. has () to funkcja, która zwraca 1, jeśli 2. ciąg znajduje się w pierwszym. inp jest łańcuchem wejściowym tej funkcji. misc jest znakiem bez znaku zainicjowanym na 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;

Przechowuję więc 7 wartości logicznych w jednej liczbie całkowitej z miejscem na więcej.

Alan Corey
źródło
Ta odpowiedź jest tak ciepła dla serca w perspektywie CS. :)
varun
2

Można uprościć powyższe równania, stosując następujące czynności:

boolean flag = sqlInt != 0;

Jeśli int reprezentacja (sqlInt) wartości logicznej wynosi 0 (fałsz), wartość logiczna (flaga) będzie fałszywa, w przeciwnym razie będzie to prawda.

Zwięzły kod jest zawsze ładniejszy w pracy :)

Głodny Androider
źródło
-4

Innym sposobem na to jest kolumna TEKST. A następnie przekonwertuj wartość logiczną między logiczną i ciąg przed / po zapisaniu / odczytaniu wartości z bazy danych.

Dawny. Ty masz"boolValue = true;

Do ciągu:

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

I wracając do boolean:

//convert the string back to boolean
bool Boolvalue = Convert.ToBoolean(StringValue);
Niels Schmidt
źródło
6
@Craig McMahon sugeruje użycie Integer zamiast: liczby pierwsze stanowią prawdziwe, nie-liczby pierwsze stanowią fałszywe
Berik
18
Uważam to za bardzo obraźliwe, @Berik. Oczywistym rozwiązaniem jest wyrenderowanie słowa „PRAWDA” lub „FAŁSZ” na obrazie, a następnie zapisanie go w wierszu bazy danych jako BLOB w formacie JPEG. Następnie można odczytać wartość z powrotem za pomocą prostego algorytmu ekstrakcji funkcji.
Craig McMahon,