Boole değerini SQLite'de depola


284

SQLite'ta bir BOOL değeri türü nedir? DOĞRU / YANLIŞ değerler tablosunda saklamak istiyorum.

INTEGER sütunu oluşturabilir ve 0 veya 1 değerlerinde saklayabilirim, ancak BOOL türünü uygulamanın en iyi yolu olmayacaktır.

Bir yolu var mı?

Teşekkürler.


Yanıtlar:


365

SQLite için yerel bir boolean veri türü yoktur. Datatypes dokümanı uyarınca :

SQLite'nin ayrı bir Boolean depolama sınıfı yoktur. Bunun yerine, Boolean değerleri 0 (yanlış) ve 1 (doğru) tamsayıları olarak saklanır.


24
"INTEGER. Değer, değerin büyüklüğüne bağlı olarak 1, 2, 3, 4, 6 veya 8 baytta depolanan işaretli bir tamsayıdır." Sanırım bir BOOL saklamak için 1 bayt kullanmak çok kötü değil.
joce

2
Doğrudan At'ın ağzından: "SQLite'nin ayrı bir Boolean depolama sınıfı yoktur. Bunun yerine, Boolean değerleri 0 (yanlış) ve 1 (doğru) tamsayıları olarak depolanır."
Tobias

3
Hangi performans açısından daha iyi! string / 0/1 tamsayı olarak true / false?
Muhammed Babar

9
@MuhammadBabar 0/1 kesinlikle. Dizeler daha yavaştır ve daha fazla yer kaplar.
Davor

1
@joce Aslında, 0 ve 1 tamsayıları (ve NULL) doğrudan satır veri türü bildiriminde kodlanır. Bu nedenle, yalnızca gerçek veri depolama alanını sayarsanız, boolean başına sıfır bayttır, bu harika. Yine de dosya biçimi için gereken satır başına sütun başına hesap tutma sayıyorsanız, tüm veri türlerinde fazladan bir bayt gerekir, bu harika değildir. :) (başvuru: sqlite.org/fileformat.html#record_format )
relative_random

93

SQLite'de yapabileceğiniz en iyi şey yanlış ve doğru olanı temsil etmek için 0 ve 1 tam sayılarını kullanmaktır. Sütun türünü şu şekilde bildirebilirsiniz:

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

0 ve 1'e ek olarak NOT NULLizin vermek istiyorsanız, atlayın NULL.

BOOLEANBurada tür adının kullanımı okunabilirlik içindir, SQLite için sadece NUMERIC yakınlığına sahip bir türdür .

CHECK kısıtlamalarının SQLite 3.3.0 (2006) 'dan bu yana desteklendiğini unutmayın .

İşte bazı örnek INSERT'ler: (dizelerin ve kayan nokta sayılarının tamsayı olarak nasıl ayrıştırıldığına dikkat edin)

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

ve bazıları başarısız olacak:

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

SQLite Boolean Veri Türü: SQLite'nin
ayrı bir Boolean depolama sınıfı yoktur. Bunun yerine, Boolean değerleri 0 (yanlış) ve 1 (doğru) tamsayıları olarak saklanır.

Boolean yazılımını int biçimine şu şekilde dönüştürebilirsiniz:

int flag = (boolValue)? 1 : 0;

İnt'i aşağıdaki gibi boole'ye dönüştürebilirsiniz:

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

Eğer sqlite keşfetmek istiyorsanız, işte bir öğretici . Burada
bir cevap verdim . Onlar için çalışıyor.


13
kodun son satırı sadece "Boolean flag2 = (intValue == 1)" olabilir
cja

16
Ben önermekBoolean flag2 = (intValue != 0);
Hamzeh Soboh

ya da sadece Boolean flag2 = (intValue> 0) yapabilirsiniz;
Efrain Sanjay Adhikary


5

Ericwa'nın cevabına ek olarak. CHECK kısıtlamaları, bir METİN veri türünü zorlayarak ve yalnızca TRUE veya FALSE büyük / küçük harf durumuna özel değerlere izin vererek sözde bir boole sütununu etkinleştirebilir.

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

Ancak, bir grup saklamak istiyorsanız, onları biraz değiştirebilir ve hepsini tek bir int olarak, biraz unix dosya izinleri / modları gibi saklayabilirsiniz.

Örneğin 755 modu için, her bir basamak farklı bir kullanıcı sınıfını ifade eder: sahip, grup, genel. Her bir basamakta 4 okunur, 2 yazılır, 1 yürütülür, böylece 7 hepsi ikili 111 gibidir. 5 okunur ve yürütülür 101. Kendi kodlama şemanızı oluşturun.

Sadece Schedules Direct'ten TV programı verilerini depolamak için bir şeyler yazıyorum ve ikili veya evet / hayır alanlarına sahibim: stereo, hdtv, yeni, ei, altyazılı, dolby, İspanyolca İspanyolca, sezon prömiyeri. Yani 7 bit veya maksimum 127 olan bir tam sayı. Bir karakter gerçekten.

Şu anda üzerinde çalıştığım şeyden bir AC örneği. has () işlevi, 2. dize ilk satırdaysa 1 döndüren bir işlevdir. inp, bu işlevin giriş dizesidir. misc, 0 olarak başlatılmış işaretsiz bir karakterdir.

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;

Bu yüzden daha fazla bilgi için oda ile bir tamsayıda 7 boolean saklıyorum.


Bu cevap, CS perspektifinde çok yüreklidir. :)
varun

2

Yukarıdaki denklemleri aşağıdakileri kullanarak basitleştirebilirsiniz:

boolean flag = sqlInt != 0;

Booleanın int gösterimi (sqlInt) 0 (yanlış) ise, boolean (bayrak) yanlış olur, aksi takdirde true olur.

Özlü kod her zaman çalışmak daha güzel :)


-4

Bunu yapmanın başka bir yolu da METİN sütunudur. Ve sonra değeri veritabanından kaydetmeden / okuduktan önce / sonra Boolean ve String arasında dönüştürün.

Ör. You have "boolValue = true;"

Dizgiye:

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

Ve boole geri dönelim:

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

6
@Craig McMahon bunun yerine Tamsayı kullanmanızı önerir: asal sayılar doğru, asal olmayanlar yanlış gösterir
Berik

19
Çok rahatsız edici buluyorum, @Berik. Bariz çözüm "TRUE" ya da "FALSE" kelimesini bir görüntüye dönüştürmek ve bunu veritabanı satırına JPEG kodlu bir BLOB olarak kaydetmek. Daha sonra basit bir özellik çıkarma algoritması kullanarak değeri geri okuyabilirsiniz.
Craig McMahon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.