SQL Query Error - If Else Statement - mysql

The following SQl query gives me the error:
IF EXISTS (SELECT * FROM comments WHERE user_id='2' AND course_id='1')
UPDATE comments SET page1='exists' WHERE user_id='2' AND course_id='1'
ELSE
INSERT INTO comments (user_id,course_id,page1) VALUES ('2','1','inserted')
" #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF EXISTS (SELECT * FROM comments WHERE user_id='2' AND course_id='1') UPDATE co' at line 1 "
I'm sure the syntax is correct?!

Add a unique key covering user_id and course_id
Then just use
INSERT INTO comments (user_id,course_id,page1)
VALUES ('2','1','inserted')
ON DUPLICATE KEY UPDATE page1='exists'

Check this IF-statement syntax:
Try this:
IF EXISTS (SELECT * FROM comments WHERE user_id='2' AND course_id='1') THEN
UPDATE comments SET page1='exists' WHERE user_id='2' AND course_id='1';
ELSE
INSERT INTO comments (user_id,course_id,page1) VALUES ('2','1','inserted');
OR
As per me you have to make practice of BEGIN...END block as shown below.
IF EXISTS (SELECT * FROM comments WHERE user_id='2' AND course_id='1') THEN
BEGIN
UPDATE comments SET page1='exists' WHERE user_id='2' AND course_id='1';
END
ELSE
BEGIN
INSERT INTO comments (user_id,course_id,page1) VALUES ('2','1','inserted');
END
My above queries will work in Procedures(PL-SQL). If you want to use above query in SQL
then use below code:
Create a UNIQUE constraint on your user_id & course_id columns, if one does not already exist:
ALTER TABLE comments ADD UNIQUE (user_id,course_id);
Use INSERT ... ON DUPLICATE KEY UPDATE:
INSERT INTO comments (user_id,course_id,page1)
VALUES ('2','1','inserted')
ON DUPLICATE KEY UPDATE page1='exists'

Related

SQL: Unrecongnized statement near conditional (IF)

I've never used IF's before in SQL. I need to update a row where institution is a specific number if it exists and insert it if it doesn't. In order to avoid using first a select and then a insert or update I wanted to try my hand at an IF statement. I figured from what I've read in the documentation that it should go something like this:
IF (NOT EXISTS(SELECT evaluations FROM tEvaluations WHERE institution = 0))
BEGIN
INSERT INTO tEvaluations (institution,evaluations) VALUES (0,0)
END
ELSE
BEGIN
UPDATE tEvaluations SET evaluations = 10 WHERE institution = 0
END
However I get this error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'BEGIN
INSERT INTO tEvaluations (institution,evaluations) VALUES (0,0)
END' at line 2
I'm trying to run this query in phpmyadmin to test out how the query should be.
You can't have if..else block in normal SQL statement unless it's inside a procedural block. To me looks like you are looking for INSERT ON DUPLICATE KEY UPDATE like
INSERT INTO tEvaluations (institution,evaluations) VALUES (0,0)
ON DUPLICATE KEY UPDATE evaluations = 10;
Per documentation, either of your column should have a UNIQUE constraint defined against it. Quoting from documentation
If you specify an ON DUPLICATE KEY UPDATE clause and a row to be
inserted would cause a duplicate value in a UNIQUE index or PRIMARY
KEY, an UPDATE of the old row occurs. For example, if column a is
declared as UNIQUE and contains the value 1

MySQL BEFORE INSERT trigger to turn duplicate primary keys inserts into updates

I'm trying to execute this query in a database through phpmyadmin
create trigger avoid_duplicated_sharing
before insert on sharingevents
for each row
begin
if ( select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0 ) then
delete from sharingevents where shared_note_id = NEW.shared_note AND shared_to = NEW.shared_to
END IF;
END
But phpmyadmin gives me the following error:
MySQL said: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'END IF' at line 7
Two questions:
What's wrong with my script?
After a BEFORE INSERT trigger, Will INSERT operation be performed? In case it doesn't I will have to remove INSERT INTO SharingEvents (SELECT * FROM NEW);
I solve it with the following code:
delimiter $$
create trigger avoid_duplicated_sharing
before insert on sharingevents
for each row
begin
if ( select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0 ) then
delete from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to;
end if;
END$$
The problem was the delimiter.
Even so, my trigger doesn't work. When the application inserts duplicated primary keys MySQL throws the following error:
#1442 - Can't update table 'sharingevents' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Use exists:
if (exists (select 1 from sharingevents where shared_note_id = new.shared_note_id AND shared_to = new.shared_to) > 0) then
insert into sharingevents (shared_note_id,shared_to,permission_level)
values (NEW.shared_note_id,NEW.shared_to,NEW.permission_level);
end if;
Or, better yet, add a unique index on sharingevents(shared_note-id, shared_to) and then use:
insert into sharingevents (shared_note_id, shared_to, permission_level)
values (NEW.shared_note_id, NEW.shared_to, NEW.permission_level)
on duplicate key update shared_note_id = values(shared_note_id);
This will ignore any updates where the pairs already exist in the table. No if required.
count(shared_note_id, shared_to) is invalid syntax. You can only put multiple column names inside COUNT() when you use count(DISTINCT ...). In your case, you don't need to put column names at all, just use COUNT(*) to count the number of rows matching the condition.
See count(*) and count(column_name), what's the diff? for more information about when you should put column names in COUNT()
Unfortunately, fixing the syntax errors won't really solve your problem, because you can't use a trigger to make a change to the same table. From the FAQ:
Can triggers access tables?
A trigger can access both old and new data in its own table. A trigger can also affect other tables, but it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
You'll need to recode the callers to use INSERT ... ON DUPLICATE KEY UPDATE, or something equivalent, to accomplish this.

Why this SQL query does not work?

I wrote this query but I get the following error:
Fatal error: Uncaught exception 'PDOException' with message
'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your
MariaDB server version for the right syntax to use near 'BEGIN INSERT
INTO forum_topics_track (userid, topic_id, `c' at line 3
I guess it is self explanatory but my goal is to check if the record exists and if it doesn't, to insert it.
IF NOT EXISTS
(SELECT * FROM `forum_topics_track` WHERE `userid` = '{$userid}' AND `topic_id` = '{$topic_id}')
BEGIN
INSERT INTO `forum_topics_track` (`userid`, `topic_id`, `category_id`)
VALUES ('{$topic_id}', '{$category_id}', '{$userid}')
END;
A faster alternative would be to have a UNIQUE INDEX on userid and topic_id.
CREATE UNIQUE INDEX forum_topics_track_ndx ON forum_topics_track(userid, topic_id);
Then you could do
INSERT IGNORE INTO `forum_topics_track` (`userid`, `topic_id`, `category_id`)
VALUES ('{$topic_id}', '{$category_id}', '{$userid}');
which would always succeed (possibly doing nothing if the data already is there).
Or you could look into the ON DUPLICATE KEY UPDATE trick.
This is the wrong way to implement the logic. If you want each user and topic to appear in forum_topics_track one time, then have the database enforce the constraint. This is easy with a unique index or constraint:
create unique index unq_forum_topics_track_user_topic on forum_topics_track(user_id, topic_id);
Then, you can do an insert and ignore or handle the error:
INSERT INTO `forum_topics_track` (`userid`, `topic_id`, `category_id`)
VALUES ('{$topic_id}', '{$category_id}', '{$userid}')
ON DUPLICATE KEY UPDATE userid = VALUES(userid);
No IF is needed in the logic. In fact, using IF just invites problems due to race conditions and doesn't really guarantee anything in the database.
IF NOT EXISTS is a clause that is available to use in MS-SQL but not in MySQL. Please try following query.
INSERT INTO `forum_topics_track` (`userid`, `topic_id`, `category_id`)
SELECT '{$topic_id}', '{$category_id}', '{$userid}'
WHERE NOT EXISTS(
SELECT * FROM `forum_topics_track` WHERE `userid` = '{$userid}' AND `topic_id` = '{$topic_id}'
)

MySQL trigger if-else insert update

I'm trying to make this code work but to no avail..
DELIMITER $$
CREATE
TRIGGER `update_tbl1` AFTER UPDATE
ON `tbl1`
FOR EACH ROW BEGIN
IF (SELECT count(*) FROM tbl1 WHERE stn=NEW.stn) = 1
THEN
UPDATE tbl2 SET date_posted=NEW.date_posted WHERE stn=NEW.stn;
ELSE
INSERT INTO tbl2 (stn) VALUES (NEW.stn);
END IF
END$$
DELIMITER ;
I have two tables, and I want a trigger that will update tbl2 if the tbl1 is updated, only if the data already exists on the tbl2, otherwise, insert it. My code seems feasible and the error seems to be syntax-related but I can't find where.
EDIT:
Here is the error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO tbl2 (stn) VALUES (NEW.stn); END IF END' at line 10
About syntax error, I think it's just what you forgot semicolon ; after END IF, try following:
DELIMITER $$
CREATE
TRIGGER `update_tbl1` AFTER UPDATE
ON `tbl1`
FOR EACH ROW BEGIN
IF (SELECT count(*) FROM tbl1 WHERE stn=NEW.stn) = 1
THEN
UPDATE tbl2 SET date_posted=NEW.date_posted WHERE stn=NEW.stn;
ELSE
INSERT INTO tbl2 (stn) VALUES (NEW.stn);
END IF;
END$$
DELIMITER ;
I'm not sure what the syntax error is, but the logic you want is:
INSERT INTO tbl2 (stn)
VALUES (NEW.stn)
ON DUPLICATE KEY UPDATE SET date_posted = NEW.date_posted;
For this to work, you need a unique index on tbl2(stn):
CREATE UNIQUE INDEX unq_tbl2_stn ON tbl2(stn);
Note: This doesn't fix your particular syntax error. This addresses a logical error in the code.

mysql if exists giving error wrong syntax?

I am trying to use IF EXISTS in MySQL but i keep getting syntax errors and I have researched for correct syntax but everything isnt working...
What i need is:
If query exists then UPDATE else INSERT new...
$queryString = "IF EXISTS (SELECT * FROM $ONCALL_TABLE WHERE uid='$contextUser' AND submitid='$submitid' AND submitstatus=3) THEN UPDATE $ONCALL_TABLE SET uid='$contextUser', start_time='$onStr', end_time='$offStr', amount='$amount' ELSE INSERT INTO $ONCALL_TABLE (uid, start_time, end_time, amount) VALUES ('$contextUser','$onStr', '$offStr', '$amount') END IF";
Error message:
Can't perform query: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF EXISTS (SELECT * FROM timesheet_oncall WHERE uid='admin' AND submitid='136545' at line 1
REPLACE INTO is what you need. http://dev.mysql.com/doc/refman/5.0/en/replace.html
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
In your case
REPLACE INTO
$ONCALL_TABLE (uid, start_time, end_time, amount)
VALUES ('$contextUser','$onStr', '$offStr', '$amount')
WHERE uid='$contextUser';
Assuming uid is a PRIMARY KEY or UNIQUE KEY
NOTE: Since the code in your question contains SQL injection flaws I would recommend you to read this article. http://php.net/manual/en/security.database.sql-injection.php