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
Related
I have created a table as below:
CREATE TABLE case_status(data_entry_timestamp DATETIME DEFAULT (datetime('now','localtime')) NOT NULL,
case_number TEXT PRIMARY KEY NOT NULL,
case_name TEXT DEFAULT MISSING,
death_reportdate DATE CONSTRAINT death_reportdate_chk CHECK (death_reportdate==strftime('%Y-%m-%d',death_reportdate)),
);
The column death_reportdate need to have a date with pre-defined format (e.g. 2000-12-31). I created the table, inserted some rows of data, and then try to modified data in death_reportdate, the check rule seems to be bypassed when I enter some random string to it.
What have I done wrong?
You had an extra comma at the end. Correct code:
CREATE TABLE case_status(data_entry_timestamp DATETIME DEFAULT (datetime('now','localtime')) NOT NULL,
case_number TEXT PRIMARY KEY NOT NULL,
case_name TEXT DEFAULT MISSING,
death_reportdate DATE CONSTRAINT death_reportdate_chk CHECK (death_reportdate==strftime('%Y-%m-%d',death_reportdate))
)
it is an old Topic but i had the the same Problem. if the strftime method Fails to Format the string( a bad Input) it retuns null, so you have to check is not null in the end
Here is another solution which works like a charm:
`date` DATE CHECK(date IS strftime('%Y-%m-%d', date))
This also works with the time:
`time` TIME CHECK(time IS strftime('%H:%M:%S', time))
Use this to define your column. I think that is a more elegant solution than checking for null value.
First, two small notes.
I'm using the TEXT type since SQLite does not have "real types." It has 5 column "affinities", INTEGER, TEXT, BLOB, REAL, and NUMERIC. If you say DATE then it uses NUMERIC which can behave a little weirdly in my opinion. I find it best to explicitly use one of the 5 affinities.
I'm using date(...) instead of strftime('%Y-%m-%d', ...) because they are the same thing.
Let's break down why the original question did not work.
DROP TABLE IF EXISTS TEMP.example;
CREATE TEMPORARY TABLE example (
deathdate TEXT CHECK (deathdate == date(deathdate))
);
INSERT INTO TEMP.example (deathdate) VALUES ('2020-01-01');
INSERT INTO TEMP.example (deathdate) VALUES ('a');
INSERT INTO TEMP.example (deathdate) VALUES (NULL);
SELECT * FROM TEMP.example;
Running this lets all three values get into the database. Why? Let's check the documentation for CHECK constraints.
If the result is zero (integer value 0 or real value 0.0), then a constraint violation has occurred. If the CHECK expression evaluates to NULL, or any other non-zero value, it is not a constraint violation.
If you run SELECT 'a' == date('a'); you'll see it is NULL. Why? Check SELECT date('a'); and you'll see it is also NULL. Huh, maybe the documentation for == can help?
Note that there are two variations of the equals and not equals operators. Equals can be either = or ==. [...]
The IS and IS NOT operators work like = and != except when one or both of the operands are NULL. In this case, if both operands are NULL, then the IS operator evaluates to 1 (true) and the IS NOT operator evaluates to 0 (false). If one operand is NULL and the other is not, then the IS operator evaluates to 0 (false) and the IS NOT operator is 1 (true). It is not possible for an IS or IS NOT expression to evaluate to NULL.
We need to use IS, not ==, and trying that we see that 'a' no longer gets in.
DROP TABLE IF EXISTS TEMP.example;
CREATE TEMPORARY TABLE example (
deathdate TEXT CHECK (deathdate IS date(deathdate))
);
INSERT INTO TEMP.example (deathdate) VALUES ('2020-01-01');
INSERT INTO TEMP.example (deathdate) VALUES ('a');
INSERT INTO TEMP.example (deathdate) VALUES (NULL);
SELECT * FROM TEMP.example;
If you don't want NULL to get in, simple change it to deathdate TEXT NOT NULL CHECK (deathdate IS date(deathdate))
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
I have a trigger.
I want to do insert changed values after every update.
But I get syntax error on line IF .. THEN, and I can't find example.
IF (IFNULL(NEW.symbol,'') <> IFNULL(OLD.symbol,'')) THEN
INSERT INTO LOG(old_value, new_value, DATA, user)
VALUES ('Symbol: '|| IFNULL(OLD.symbol,''), 'Symbol: ' (IFNULL(NEW.symbol,''), CURRENT_TIMESTAMP, id_user)
Can You help me?
SQLite has no IF statement.
You must put the condition into the WHEN clause of the trigger.
I have a table named CUSTOMER, with few columns. One of them is Customer_ID.
Initially Customer_ID column WILL NOT accept NULL values.
I've made some changes from code level, so that Customer_ID column will accept NULL values by default.
Now my requirement is that, I need to again make this column to accept NULL values.
For this I've added executing the below query:
ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL
I'm getting the following error:
ORA-01451 error, the column already allows null entries so
therefore cannot be modified
This is because already I've made the Customer_ID column to accept NULL values.
Is there a way to check if the column will accept NULL values before executing the above query...??
You can use the column NULLABLE in USER_TAB_COLUMNS. This tells you whether the column allows nulls using a binary Y/N flag.
If you wanted to put this in a script you could do something like:
declare
l_null user_tab_columns.nullable%type;
begin
select nullable into l_null
from user_tab_columns
where table_name = 'CUSTOMER'
and column_name = 'CUSTOMER_ID';
if l_null = 'N' then
execute immediate 'ALTER TABLE Customer
MODIFY (Customer_ID nvarchar2(20) NULL)';
end if;
end;
It's best not to use dynamic SQL in order to alter tables. Do it manually and be sure to double check everything first.
Or you can just ignore the error:
declare
already_null exception;
pragma exception_init (already_null , -01451);
begin
execute immediate 'alter table <TABLE> modify(<COLUMN> null)';
exception when already_null then null;
end;
/
You might encounter this error when you have previously provided a DEFAULT ON NULL value for the NOT NULL column.
If this is the case, to make the column nullable, you must also reset its default value to NULL when you modify its nullability constraint.
eg:
DEFINE table_name = your_table_name_here
DEFINE column_name = your_column_name_here;
ALTER TABLE &table_name
MODIFY (
&column_name
DEFAULT NULL
NULL
);
I did something like this, it worked fine.
Try to execute query, if any error occurs, catch SQLException.
try {
stmt.execute("ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL");
} catch (SQLException sqe) {
Logger("Column to be modified to NULL is already NULL : " + sqe);
}
Is this correct way of doing?
To modify the constraints of an existing table
for example... add not null constraint to a column.
Then follow the given steps:
1) Select the table in which you want to modify changes.
2) Click on Actions.. ---> select column ----> add.
3) Now give the column name, datatype, size, etc. and click ok.
4) You will see that the column is added to the table.
5) Now click on Edit button lying on the left side of Actions button.
6) Then you will get various table modifying options.
7) Select the column from the list.
8) Select the particular column in which you want to give not null.
9) Select Cannot be null from column properties.
10) That's it.
I'm preety new to SQLite.
I have a preety basic question.. Why can't I select rows where specific column equals zero?
The is_unwanted column is type TINYINT (which I see in SQLite basically means INTEGER)
So, I have only one record in the database (for testing).
When I try
SELECT is_unwanted FROM 'urls'
I get a result of "0" (zero), which is fine because that column contains the actual number 0.
I tried =>
SELECT * FROM 'urls' WHERE is_unwanted = 0
And got NO result, but
SELECT * FROM 'urls' WHERE is_unwanted <> 0
gives me result.
What am I doing wrong??
Try running
select '{' || is_unwanted || '}' from urls
to see if the value in the database is really a string containing spaces.
SQLite is a dynamically typed database; when you specify TINYINT is is a hint (SQLite uses the term "affinity") for the column. You can use
select is_unwanted, typeof(is_unwanted) from urls
to see the values with their types.
You could try:
SELECT * FROM urls WHERE coalesce(is_unwanted,'') = ''