IF NOT EXIST NOT WORKING - mysql

IF NOT EXISTS(SELECT * FROM `user` WHERE `name`='Rutvij' AND `lang`='python')
BEGIN
INSERT INTO `user` VALUES ('Rutvij', 'python', 25)
END
ELSE
BEGIN
UPDATE user SET `name`='Kanzaria' WHERE `name`='Rutvij'
END
I am trying the above query in phpmyadmin sql area. I am using xampp. It is throwing error stating that
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 user)
SELECT name FROM use' at line 1
I have also tried the below code
IF NOT EXISTS(SELECT * FROM user WHERE name='Rutvij' AND lang='python')
BEGIN
INSERT INTO user VALUES ('Rutvij', 'python', 25)
END
ELSE
BEGIN
INSERT INTO user VALUES ('Kanzaria', 'python', 25)
END
Struggling for so long. Kindly help. Thanks!!

MySQL doesn't permit if logic, unless you are in a programming block (stored procedure, trigger, or function).
Fortunately, you can do the same with WHERE logic:
INSERT INTO user
SELECT 'Rutvij', 'python', 25
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM user WHERE name = 'Rutvij' AND lang = 'python')
UNION ALL
SELECT 'Kanzaria', 'python', 25
FROM DUAL
WHERE EXISTS (SELECT 1 FROM user WHERE name = 'Rutvij' AND lang = 'python');
MySQL should process the SELECT before the INSERT, so only one row should be inserted.
Or, you can do this as two INSERTs but in the opposite order:
INSERT INTO user
SELECT 'Kanzaria', 'python', 25
FROM DUAL
WHERE EXISTS (SELECT 1 FROM user WHERE name = 'Rutvij' AND lang = 'python');
INSERT INTO user
SELECT 'Rutvij', 'python', 25
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM user WHERE name = 'Rutvij' AND lang = 'python');

This is not a query, this would be an sql script with control flow logic, which is not allowed in mysql outside stored programs (procedures, functions, triggers). Even if you encapsulated the above code into a stored procedure it would not work because exist / not exists can only be used in subqueries.
I would do the following:
Create a stored procedure
Declare an integer variable
Using select into fetch the count of rows where name='Rutvij' AND lang='python' into your variable.
Use the if statement to do the insertion based on the number of records.

Related

How to create stored procedure that inserts both input and data from select statement after first insert

I am trying to create a stored procedure in MySQL that will add rows to two different tables. The first table (sites) has an id column set to auto_increment which I would like to include in the second insert statement to the sitesByUser table. I've tried some ideas based off this excellent post: https://dba.stackexchange.com/questions/2973/how-to-insert-values-into-a-table-from-a-select-query-in-postgresql but I get various errors, such as the one listed below. I suspect that part of my problem is that I'm trying to both add both userInput and SELECT id FROM sites WHERE id=LAST_INSERT_ID() to the same table, but I'm not sure what to do to get that to work.
CREATE PROCEDURE createSite(IN siteName VARCHAR(2048), IN userInput VARCHAR(255))
BEGIN
INSERT INTO sites(siteName, user) VALUES (siteName, userInput);
INSERT INTO sitesByUser(user, site) userInput, SELECT id FROM sites WHERE id=LAST_INSERT_ID();
SELECT * FROM sitesByUser WHERE id=LAST_INSERT_ID();
END
The response from MySQL:
Error while performing Query.
ER_PARSE_ERROR
ER_PARSE_ERROR: 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 'userInput, SELECT id FROM sites WHERE id=LAST_INSERT_ID();
SELECT * FROM sitesBy' at line 3
Try this
SET #last_id_in_table1 = LAST_INSERT_ID();
SELECT * FROM sitesByUser WHERE id=#last_id_in_table1;
Hope this helps
It seems that the correct way to do this is to store the LAST_INSERT_ID() in a variable as described here: How to declare a variable in MySQL? I'm not sure that I should be using the # symbol in front of the variable since that seems to make it a user-defined variable which means it is session-specific which is probably too wide in scope for my needs, but so far, this successfully creates a stored procedure that I think will work. I'll update this post if it does not.
CREATE PROCEDURE createSite(IN siteName VARCHAR(2048), IN userInput VARCHAR(255))
BEGIN
INSERT INTO sites(siteName, user) VALUES (siteName, userInput);
SET #last_id_in_sites = LAST_INSERT_ID();
INSERT INTO sitesByUser(user, site) VALUES (userInput, #last_id_in_sites);
SELECT * FROM sitesByUser WHERE id=LAST_INSERT_ID();
END

MySQL workbench error 1064 when adding trigger

I am new to SQL and more specifically using MySQL Workbench.
I have created a database with two tables Grades and GPAList.
I want to take the average value of every entry in Grades (grouped by student id [sid is the name of the column]) once I have those averages, store them in the GPAList table with their corresponding students. This is intended to trigger every time a new entry is added to Grades.
This is the trigger that I have created:
CREATE DEFINER = CURRENT_USER TRIGGER `ProjectName`.`Grades_AFTER_UPDATE_1` AFTER UPDATE ON `Grades` FOR EACH ROW
BEGIN
SELECT sid, SUM ( CASE grade
when 'A' then 4.0
when 'B' then 3.5
when 'C' then 3.0
when 'D' then 2.5
when 'F' then 1.0
else 0
end
) / COUNT(*) Grades
INTO GPAList
FROM Grades
GROUP BY sid;
END
The error that I am encountering is:
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 '' at
line 1 SQL Statement: CREATE DEFINER = CURRENT_USER TRIGGER
`ProjectName`.`Grades_AFTER_UPDATE_1` AFTER UPDATE ON `Grades` FOR EACH ROW
FOLLOWS `Grades_AFTER_UPDATE`
When I write this code in the workbench, no syntax errors are shown. When I try to apply this trigger, my code is converted to:
DROP TRIGGER IF EXISTS `ProjectName`.`Grades_AFTER_UPDATE_1`;
DELIMITER $$
USE `ProjectName`$$
CREATE DEFINER = CURRENT_USER TRIGGER `ProjectName`.`Grades_AFTER_UPDATE_1` AFTER UPDATE ON `Grades` FOR EACH ROW FOLLOWS `Grades_AFTER_UPDATE`
$$
DELIMITER ;
Only after clicking apply once more do I see the 1064 error listed above. Is there some easy fix that I am missing?
There is a Grades_AFTER_UPDATE that Grades_AFTER_UPDATE_1 is following, so that shouldn't be the problem.
I'm not sure why you would want to store all averages after a single insert, but the correct insert logic is something like this:
INSERT INTO GPALIST(sid, grades)
SELECT sid,
AVG (CASE grade
when 'A' then 4.0
when 'B' then 3.5
when 'C' then 3.0
when 'D' then 2.5
when 'F' then 1.0
else 0
end) as Grades
FROM Grades
GROUP BY sid;
I suspect the trigger would want to access new. somewhere along the way.

INSERT WHERE EXISTS

For MySQL, If I stored the userid and a token in the user table and only allows to insert record in another table if the supplied userid and token matches.I've tried
INSERT INTO product(description)
VALUES('123')
WHERE EXISTS
(SELECT 1 FROM users where userid='myuserid' AND token='ABCD')
The following SQL statement produces error
"check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE EXISTS (SELECT 1 FROM users where userid='29')'"
However for update I can update successfully with
UPDATE product
SET description='123'
WHERE EXISTS
(SELECT 1 FROM users where userid='myuserid' AND token='ABCD')
Can any experts please help to advise.
I need the most efficient way to verify the user token is correct before doing the insert.
Please try using a trigger instead:
CREATE TRIGGER tokenValidator
BEFORE INSERT
ON product
FOR EACH ROW BEGIN
IF (SELECT 1 FROM users where userid='myuserid' AND token='ABCD') THEN
INSERT INTO product(description) VALUES('123')
END IF

MySQL CREATE PROCEDURE syntax error

I've tried every possible combination I can think of to resolve this error but it keeps happening. Any help appreciated. This is just modifying the sakila sample database to do more complex things with.
See towards bottom I labeled the error with -- HERE!.
USE sakila;
DROP PROCEDURE IF EXISTS sp_randCustMult;
DELIMITER //
CREATE PROCEDURE sp_randCustMult()
BEGIN
/* section of code left out for troubleshooting
IF EXISTS (SELECT * FROM information_schema.columns WHERE table_name = customer AND column_name = multiplier)
THEN ALTER TABLE customer DROP COLUMN multiplier;
IF EXISTS (SELECT * FROM information_schema.columns WHERE table_name = customer AND column_name = cust_ranking)
THEN ALTER TABLE customer DROP COLUMN cust_ranking;
END IF;
*/
-- add new columns
ALTER TABLE customer
ADD COLUMN multiplier DECIMAL(3,2) AFTER active;
/* this column not relevant now
ALTER TABLE customer
ADD COLUMN cust_ranking VARCHAR(10) AFTER multiplier;
*/
-- declare a counter
SET #start = (SELECT MIN(customer_id) FROM customer);
SET #stop = (SELECT MAX(customer_id) FROM customer);
-- start while loop
WHILE #start <= #stop
DO
UPDATE customer
-- insert multiplier based on random distribution
SET multiplier =
(SELECT
(CASE
WHEN RAND() <= 0.65 THEN 1.00
WHEN RAND() <= 0.90 THEN 0.85
WHEN RAND() <= 1.00 THEN 1.05
END)
)
WHERE customer_id = #start;
-- tick counter one up
SET #start = #start + 1;
END WHILE;
-- HERE! syntax error on END before //
END//
DROP PROCEDURE sp_randCustMult//
DELIMITER ;
EDIT1: To clarify, MySql version is:
MySQL Workbench Community (GPL) for Mac OS X version 6.1.4 revision 11773 build 1454
And the error response from Workbench:
Error Code: 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 'END' at line 35
EDIT2: Edited code as suggested. Error no longer happens, however data is not being updated at all. (all NULL in new column)
Your CREATE PROCEDURE doesn't match the required syntax as described in the MySQL manual (simplified below by including just the relevant parts):
CREATE
    PROCEDURE sp_name ([proc_parameter[,...]])
    routine_body
routine_body:
    Valid SQL routine statement
The routine_body consists of a valid SQL routine statement. This can be a simple statement such as SELECT or INSERT, or a compound statement written using BEGIN and END. Compound statements can contain declarations, loops, and other control structure statements. The syntax for these statements is described in Section 13.6, “MySQL Compound-Statement Syntax”.
Therefore, this junk…
IF EXISTS (SELECT * FROM information_schema.columns WHERE table_name = customer AND column_name = multiplier)
THEN ALTER TABLE customer DROP COLUMN multiplier;
IF EXISTS (SELECT * FROM information_schema.columns WHERE table_name = customer AND column_name = cust_ranking)
THEN ALTER TABLE customer DROP COLUMN cust_ranking;
END IF;
… is illegal. Perhaps you meant to move it into the BEGIN … END compound statement?
You also need a semicolon after END WHILE.
All functional logic must be between the tags BEGIN and END
So the IF conditions and alter query stuff must lie between BEGIN and END tags of procedure..
Thanks
I figured out the issues, here is the solution on CR:
https://codereview.stackexchange.com/questions/51603/mysql-modifying-sakila-database

sql if exists simple syntax error

I keep getting this syntax error but can't find anything wrong with it when comparing to other examples.
if EXISTS (select 1 from City where name = 'Perth')
THEN Print 'Record exits - Update'
ELSE Print 'Record doesn''t exist - Insert'
I find 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 'if EXISTS (select
1 from City where name = 'Perth') THEN Print 'Record e' at line 1
I get this both on zend cloud and normal phpmyadmin mysql 5
That isn't actually a valid MySQL query. It looks like you are trying to mix together SQL with how you want to display output based on the whether the query exists or not. You can use this to return whether or not Perth exists in SQL:
SELECT EXISTS(SELECT 1 FROM City WHERE name = 'Perth')
This will return 1 or 0, which you can then parse with your server-side scripts. The reason it is giving you a syntax error is because MySQL IF statements take the form IF(condition, <action if true>, <action if false>), with no use of THEN or ELSE (as is common in programming languages). Also, MySQL doesn't have an explicit PRINT statement, but you could use SELECT to somewhat accomplish what you want above (note that we can remove EXISTS as False will be implied if the result returns nothing):
SELECT IF(
(SELECT 1 FROM City WHERE name = 'Perth'),
(SELECT 'Record exists - update'),
(SELECT 'Record does not exist - Insert')
)
You need to use 'select' instead of print in following way
select IF((select 1 from city where name='Perth'),
'Record exits - Update','Record does not exist - Insert');
SQL Fiddle Demo. Following shows the use of IF in select Statement
IF((select 1 from city where name='Perth'),
'Record exits - Update','Record does not exist - Insert');
IF contains two messages.
First : 'Record exits - Update' Second : 'Record does not exist - Insert'
First message is printed if (select 1 from city where name='Perth') has some results(equivalent to EXISTS) otherwise you will get second message
An alternative way: using a grouping function will always return a record. If there are no records to operate on, the result of the group by function will be NULL. You could use that as a decision mechanism.
postgres=# create table city(name text);
CREATE TABLE
postgres=#
postgres=# select COALESCE( max('Record exists - Update'), 'Record doesn''t exist - Insert' ) as state
postgres-# from city
postgres-# where name = 'Perth';
state
-------------------------------
Record doesn't exist - Insert
(1 row)
postgres=#
postgres=# insert into city values('Perth');
INSERT 0 1
postgres=#
postgres=# select COALESCE( max('Record exists - Update'), 'Record doesn''t exist - Insert' ) as state
postgres-# from city
postgres-# where name = 'Perth';
state
------------------------
Record exists - Update
(1 row)