Зберігати булеве значення в SQLite


284

Який тип значення BOOL у SQLite? Я хочу зберегти у своїй таблиці значення ІСТИНА / ЛІЖНЯ.

Я міг би створити стовпець INTEGER і зберігати в ньому значення 0 або 1, але це не буде найкращим способом реалізації типу BOOL.

Чи є спосіб?

Дякую.


Відповіді:


365

Немає вбудованого булевого типу даних для SQLite. Відповідно до документа Datatypes :

SQLite не має окремого класу зберігання Boolean. Натомість булеві значення зберігаються як цілі числа 0 (хибні) та 1 (істинні).


24
"INTEGER. Значення - це підписане ціле число, збережене в 1, 2, 3, 4, 6 або 8 байтах залежно від величини значення." Я думаю, що використовувати 1 байт для зберігання BOOL - це не так вже й погано.
жарт

2
Прямо з уст Коня: "SQLite не має окремого булевого класу зберігання. Натомість булеві значення зберігаються як цілі числа 0 (хибні) та 1 (істинні)."
Тобіас

3
Що краще в плані виконання! true / false як рядки або 0/1 ціле число?
Мухаммед Бабар

9
@MuhammadBabar 0/1 найвиразніше. Струни повільніші і займають більше місця.
Давор

1
@joce Насправді цілі числа 0 і 1 (а також NULL) кодуються безпосередньо в оголошенні про тип даних рядків. Тож це нульовий байт на булевий, якщо порахувати лише фактичне зберігання даних, що є дивним. Якщо ви рахуєте бухгалтерію за стовпцями на рядок, що вимагається форматом файлу, то всі типи даних мають додатковий байт, що не є дивним. :) (довідка: sqlite.org/fileformat.html#record_format )
порівняно_випадково

93

У SQLite найкраще, що ви можете зробити, це використовувати цілі числа 0 і 1 для представлення помилок та істинності. Ви можете оголосити тип стовпця таким:

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

Пропустіть, NOT NULLякщо ви хочете дозволити NULLдодатково 0 та 1.

Використання BOOLEANтут назви типу призначено для читабельності, для SQLite - це лише тип із спорідненістю NUMERIC .

Зауважте, що обмеження CHECK підтримуються з часу SQLite 3.3.0 (2006).

Ось кілька прикладів INSERT, які будуть працювати: (зверніть увагу на те, як рядки та числа з плаваючою комою розбираються на цілі числа)

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

і деякі, що не вдасться:

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:
SQLite не має окремого булевого класу зберігання. Натомість булеві значення зберігаються як цілі числа 0 (хибні) та 1 (істинні).

Ви можете перетворити булевий в int таким чином:

int flag = (boolValue)? 1 : 0;

Ви можете перетворити int назад в булевий наступним чином:

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

Якщо ви хочете вивчити sqlite, ось вам підручник .
Я дав тут одну відповідь . Це працює на них.


13
остаточний рядок коду може бути просто "Boolean flag2 = (intValue == 1)"
cja

16
ПропонуюBoolean flag2 = (intValue != 0);
Хамзе Собох

або ви можете просто зробити Boolean flag2 = (intValue> 0);
Ефрайн Санджай Адгікарі


5

Далі до відповіді ericwa. Перевірка обмежень може ввімкнути псевдо булеву колонку, застосовуючи тип даних TEXT і дозволяючи лише значення TRUE або FALSE, конкретні для випадку, наприклад

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

Але, якщо ви хочете зберегти купу їх, ви можете злегка змінити їх і зберегти їх як один int, трохи схожий на дозволи / режими файлів Unix.

Наприклад, у режимі 755 кожна цифра стосується іншого класу користувачів: власника, групи, загальнодоступних. У межах кожної цифри 4 читається, 2 - записується, 1 виконується, тому 7 - це все, як двійкові 111. 5 читається і виконується так 101. Складіть власну схему кодування.

Я просто пишу щось для зберігання даних телевізійного розкладу з Schedules Direct, і у мене є бінарні поля "так / ні": стерео, hdtv, new, ei, закритий титр, dolby, сап на іспанській мові, прем'єра сезону. Отже, 7 біт або ціле число з максимумом 127. Дійсно один символ.

Приклад змінного струму з того, над чим я працюю зараз. has () - це функція, яка повертає 1, якщо другий рядок знаходиться в першому. inp - це вхідний рядок до цієї функції. misc - це непідписаний знак, ініціалізований на 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;

Тому я зберігаю 7 булів в одне ціле число з простором для більше.


Ця відповідь настільки сердечно зігріває з точки зору CS. :)
varun

2

Ви можете спростити вищевказані рівняння, використовуючи наступне:

boolean flag = sqlInt != 0;

Якщо представлення int (sqlInt) булевого значення 0 (false), булеве (прапор) буде хибним, інакше воно буде істинним.

Короткий код завжди приємніше працювати з :)


-4

Ще один спосіб зробити це - ТЕКСТОВИЙ стовпець. А потім перетворять булеве значення між булевим і рядком до / після збереження / зчитування значення з бази даних.

Вих. У вас є "boolValue = true;"

До рядка:

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

І назад до булевих:

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

6
@Craig McMahon пропонує замість цього використовувати Integer: прості числа представляють істинні, непрості символи
Berik

18
Я вважаю це дуже образливим, @Berik. Очевидним рішенням є створення слова "ПРАВИЛЬНА" або "ЛАЖНА" на зображенні, а потім зберегти його у рядку бази даних у вигляді BLOB, кодованого JPEG. Потім можна прочитати значення назад, використовуючи простий алгоритм вилучення функцій.
Крейг Макмахон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.