SQL error: near "CASE": syntax error
(1) By noloader on 2024-01-10 14:39:32 [link] [source]
Hi Everyone,
I'm having trouble using CASE in place of the missing IF. I am trying to perform an INSERT if a record is missing.
According to Language Expressions, Section 7, https://www.sqlite.org/lang_expr.html:
The only difference between the following two CASE expressions is that the x expression is evaluated exactly once in the first example but might be evaluated multiple times in the second:
CASE x WHEN w1 THEN r1 WHEN w2 THEN r2 ELSE r3 END
CASE WHEN x=w1 THEN r1 WHEN x=w2 THEN r2 ELSE r3 END
The built-in iif(x,y,z) SQL function is logically equivalent to...
I can't use IFF because my script may run on older clients.
I'm getting a parse error when I place the following in my *.sql source file:
CREATE TABLE IF NOT EXISTS blacklist_lcl
(
bl_id INTEGER PRIMARY KEY AUTOINCREMENT,
bl_name VARCHAR,
bl_number INTEGER,
bl_date DATETIME
);
...
CASE
WHEN
SELECT COUNT(*) FROM blacklist_lcl WHERE bl_number="4105551212" == 0
THEN
INSERT INTO blacklist_lcl (bl_name, bl_number, bl_date) VALUES ("Spam User Test", "4105551212", datetime('now'))
END
It results in "SQL error: near "CASE": syntax error". Changing from '==' to '=' results in the same error.
My question is, how do I fix this?
(2.1) By Stephan Beal (stephan) on 2024-01-10 15:00:01 edited from 2.0 in reply to 1 [link] [source]
CASE WHEN SELECT
You need a scalar value there. Try wrapping that SELECT in (...).
Edit: then see Gunter's explanation for why the part after that can't work.
(3) By Gunter Hick (gunter_hick) on 2024-01-10 14:52:58 in reply to 1 [link] [source]
You can't. CASE is part of an expression, and expects only expressions. INSERT ... is a statement, not an expression.
(5) By anonymous on 2024-01-10 15:10:58 in reply to 3 [link] [source]
Move the conditions to decide to execute the trigger. Like this for example:
CREATE TRIGGER IF NOT EXISTS INSERT_NEW_MONSTERS BEFORE INSERT ON monsters_rioolwater WHEN (select count(*) from monsters_rioolwater WHERE Date_of_measurement == NEW.Date_of_measurement AND RWZI_code == NEW.RWZI_code) == 1
BEGIN
INSERT OR REPLACE INTO rioolwater_monsters_archive (RM_Date_of_report, RM_Date_measurement, RM_RWZI_AWZI_code, OLD_RNA_flow_per_100000, NEW_RNA_flow_per_100000, RM_Reason)
VALUES (NEW.Date_of_report, NEW.Date_of_measurement, NEW.RWZI_code,
(SELECT RNA_flow_per_100000 FROM monsters_rioolwater WHERE RWZI_CODE == NEW.RWZI_code AND Date_of_measurement == NEW.Date_of_measurement), NEW.RNA_flow_per_100000, 'Aanpassing meting');
UPDATE OR ROLLBACK monsters_rioolwater
SET RNA_flow_per_100000 = NEW.RNA_flow_per_100000,
Date_of_report = NEW.Date_of_report,
DTS_UPDATED = datetime('now')
where RWZI_code == NEW.RWZI_code
and Date_of_measurement == NEW.Date_of_measurement;
END;
(4) By SeverKetor on 2024-01-10 15:02:23 in reply to 1 [link] [source]
As noted previously, you can't do that. However, you can instead insert using select instead of VALUES, and then include a where clause that checks for the value already existing. Or add a unique index and do INSERT OR IGNORE INTO
etc. if that would work for whatever you're doing
(6.1) By Mark Lawrence (mark) on 2024-01-11 10:39:36 edited from 6.0 in reply to 1 [link] [source]
Here is how I would do it:
INSERT INTO blacklist_lcl(
bl_name,
bl_number,
bl_date
)
SELECT
"Spam User Test",
"4105551212",
DATETIME ('now')
FROM
(SELECT 1)
LEFT JOIN
blacklist_lcl
ON
bl_number = 4105551212 -- Should not use quotes for integer literals
WHERE
blacklist_lcl.rowid IS NULL
;
(7) By David Raymond (dvdraymond) on 2024-01-11 13:40:15 in reply to 6.1 [source]
Or alternatively something like this: with shouldInsert (shouldInsert) as ( select not exists (select 1 from blacklist_lcl where bl_number = 4105551212) ) insert into blacklist_lcl (bl_name, bl_number, bl_date) select insertValues.* from ( values ('Spam User Test', 4105551212, datetime('now')) ) as insertValues inner join shouldInsert on shouldInsert.shouldInsert = 1 ;