SQLite Boolean WHERE to check for 0 and NULL value - sqlite

I'm looking for a SQLite WHERE clause which will give me the records if they are:
0 (false)
NULL (false)
1 (true)
So besides 0 and 1 i also have records with NULL.
I now do a
SELECT * FROM my_table WHERE (MyBoolean IS NULL OR MyBoolean = 0) AND SomeOtherValue NOT NULL;
When using
SELECT * FROM my_table WHERE NOT MyBoolean AND SomeOtherValue NOT NULL;
The value=NULL records are not found, only the value=0 records :o(
Do i have to cast my column as a boolean?

Casting won't help here (CAST (null AS sometype) is still NULL). Anything that you can use will be more or less equivalent of the expression you use now: I find WHERE NOT COALESCE(MyBoolean,0) a bit more readable, but that's a personal preference.

Handling NULL booleans is really tricky indeed.
I don't know anything about the architecture of your code, but try to consider the following:
Make your MyBoolean NOT NULL DEFAULT TRUE (or FALSE, depends).
It might require minor code refactoring, but it will keep all the SELECTs clean, readable, and will escape you from using hacky methods.
I will repeat myself: this solution might not work if somehow your architecture is very inflexible and you cannot do this sort of refactors.
Hope this helps anybody.

json_quote translate null and false to 0, and true to 1. just use it : json_quote(X)='1'

Related

SQLite "modified" trigger which only only updates modified field if values have actually changed

I'm working on a trigger for SQLite which will update the "modified" field if & only if the data in all the columns under consideration has actually changed.
I've gotten very close with:
CREATE TRIGGER "main"."Orders_modified"
BEFORE UPDATE OF "order_date", "grand_total_in_dollars", "ship_to", "store", "more_href", "order_id", "grand_total" ON "Orders"
BEGIN
UPDATE Orders
SET modified=(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime'))
WHERE (OLD.order_id=NEW.order_id)
AND (
(OLD.order_date != NEW.order_date) OR
(OLD.grand_total_in_dollars != NEW.grand_total_in_dollars) OR
(OLD.ship_to != NEW.ship_to) OR
(OLD.store != NEW.store) OR
(OLD.more_href != NEW.more_href) OR
(OLD.grand_total != NEW.grand_total)
);
END;
The problem is, it does not work when a value is being put into any of those fields for the first time; i.e., when the old value is 'Null'. Works great otherwise.
My temporary workaround to this is to just default all the monitored fields as empty strings, but I'd like to understand why (& if) this is necessary.
Any tips as to why this may be, & any workarounds that might be available?
Many thanks in advance.
Instead of the operator != use the operator IS NOT which works when one or both of the operands are NULL:
......................................................
WHERE (OLD.order_id=NEW.order_id)
AND (
(OLD.order_date IS NOT NEW.order_date) OR
(OLD.grand_total_in_dollars IS NOT NEW.grand_total_in_dollars) OR
(OLD.ship_to IS NOT NEW.ship_to) OR
(OLD.store IS NOT NEW.store) OR
(OLD.more_href IS NOT NEW.more_href) OR
(OLD.grand_total IS NOT NEW.grand_total)
);

SQLite delete from table where condition is of boolean type

I am trying to run this query without success :
DataModule1.UniQuery5.Close;
DataModule1.UniQuery5.SQL.Clear;
DataModule1.UniQuery5.SQL.Text:='delete from mytable where job_done = "1"';
DataModule1.UniQuery5.ExecSQL;
Job_done is a boolean field.
Since SQLite has only 2 conditions for true/false (0 or 1), I am failing to understand why nothing gets deleted. Can you help me ?
try this command
delete from mytable where job_done = 1;
without quotes
It seems that sqlite does not have boolean type fields. So I changed the type to wideinteger.Now unchecked marks to '0' and checked to '-1'. Now,this way, everything works.

SQLite - update command yields null values

I'm having trouble performing some update on a SQLite database. I'm using the SQLite 3 shell for Windows.
I'm running the following command:
update resovled_chrom_counts set genus =
case resolved_name_full
when resolved_name_full is not null and resolved_name_full != ''
then substr(resolved_name_full,0,instr(resolved_name_full,' ')-1)
else
substr(original_name,0,instr(original_name,' ')-1)
end;
It seems to work on most rows, but some simply end up with a null value in their genus field. I tried checking some of them manually, by using the 'id' field of this table. For example, I found out that the row with id='kew-1' is null in it's genus field, and ran the following query:
select substr(resolved_name_full,0,instr(resolved_name_full,' ')-1)
from resovled_chrom_counts
where id='kew-1';
and to my surprise, I got a result (not null)!
Looks like the query works under the 'select' statement, but not under the 'update' statement.
Can anyone give an explanation and/or a solution?
Any help would be appreciated. Thanks!
The problem is not with the substr(resolved_name_full... but with the CASE.
A CASE expression can have two different forms:
CASE x WHEN y THEN ...: This compares the value of x against the value of y.
CASE WHEN a THEN ...: This checks whether the value of a is true or false.
The problem in the UPDATE statement is that there is a value (resolved_name_full) directly after the CASE, so the value of resolved_name_full is compared with the value of the expression resolved_name_full is not null and resolved_name_full != '', and this comparison always fails because resolved_name_full never happens to be 0 or 1.
Just use the second form of the CASE expression:
update resovled_chrom_counts set genus =
case
when resolved_name_full is not null and resolved_name_full != ''
then substr(resolved_name_full,0,instr(resolved_name_full,' ')-1)
else
substr(original_name,0,instr(original_name,' ')-1)
end;
SQLFiddle

pl sql decode function for use to check two values

In the select statement i need to return a value based on the data on other two colomns. For example,
select clarify, clarify_rece_date, clarify_process_date
from test_db;
So the clarify should return yes if both clarify_rece_date and clarify_process_date is not null and if they null clarify should return No.
I could have use decode here if i want to check only onle column as below,
select decode(clarify_rece_date, null,'Yes','No') clarify, clarify_rece_date, clarify_process_date
from test_db;
But how can i check for both columns in this scenario?
You could have a rather complex DECODE. However, it would make far more sense to use a CASE statement
SELECT (CASE WHEN clarify_rece_date IS NOT NULL AND
clarify_process_date IS NOT NULL
THEN 'Yes'
ELSE 'No'
END) clarify,
clarify_rece_date,
clarify_process_date
FROM test_db

How do I use a boolean field in a where clause in SQLite?

It seems like a dumb question, and yet. It could be my IDE that's goofing me up. Here's the code (this is generated from DbLinq):
SELECT pics$.Caption, pics$.Id, pics$.Path, pics$.Public, pics$.Active, portpics$.PortfolioID
FROM main.Pictures pics$
inner join main.PortfolioPictures portpics$ on pics$.Id = portpics$.PictureId
WHERE portpics$.PortfolioId = 1 AND pics$.Id > 0
--AND pics$.Active = 1 AND pics$.Public = 1
ORDER BY pics$.Id
If I run this query I get three rows back, with two boolean fields called Active and Public. Adding in the commented out line returns no rows. Changing the line to any of the following:
pics$.Active = 'TRUE'
pics$.Active = 't'
pics$.Active = boolean(1)
It doesn't work. Either errors or no results. I've googled for this and found a dearth of actual SQL queries out there. And here we are.
So: how do I use a boolean field in a where clause in SQLite?
IDE is SQLite Administrator.
Update: Well, I found the answer. SQLite Administrator will let you make up your own types apparently; the create SQL that gets generated looks like this:
CREATE TABLE [Pictures] ([Id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[Path] VARCHAR(50) UNIQUE NOT NULL,[Caption] varchAR(50) NULL,
[Public] BOOLEAN DEFAULT '0' NOT NULL,[Active] BOOLEAN DEFAULT '1' NOT NULL)
The fix for the query is
AND pics$.Active = 'Y' AND pics$.Public = 'Y'
The real issue here is, as the first answerer pointed out, there is no boolean type in SQLite. Not an issue, but something to be aware of. I'm using DbLinq to generate my data layer; maybe it shouldn't allow mapping of types that SQLite doesn't support. Or it should map all types that aren't native to SQLite to a string type.
You don't need to use any comparison operator in order to compare a boolean value in your where clause.
If your 'boolean' column is named is_selectable, your where clause would simply be:
WHERE is_selectable
SQLite does not have the boolean type: What datatypes does SQLite support?
The commented-out line as it is should work, just use integer values of 1 and 0 in your data to represent a boolean.
SQLite has no built-in boolean type - you have to use an integer instead. Also, when you're comparing the value to 'TRUE' and 't', you're comparing it to those values as strings, not as booleans or integers, and therefore the comparison will always fail.
Source: http://www.sqlite.org/datatype3.html
--> This Will Give You Result having False Value of is_online field
select * from device_master where is_online!=1
--> This Will Give You Result having True Value of is_online field
select * from device_master where is_online=1

Resources