I wrote a MYSQL Procedure for my user registration page, I have already written the PHP part to send data from there to MySQL, and it works fine (tried with a dummy data and retrieval). But there is some sort of problem with my handler or transaction I guess
This is my Procedure:
BEGIN
DECLARE unamec INT;
DECLARE emailc INT;
DECLARE m INT;
DECLARE msg VARCHAR(100);
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET m=1;
START TRANSACTION;
SET autocommit=0;
SELECT COUNT(*) INTO unamec FROM login WHERE uname=`#user`;
IF unamec=0 THEN
SELECT COUNT(*) INTO emailc FROM login WHERE email=#email;
IF emailc=0 THEN
INSERT INTO login (uname, hash, email, role) values(#user,MD5(#password),#email,'1');
SET msg='Successfully Registered';
ELSE
SET msg='Email Already Exists';
END IF;
ELSE
SET msg='Username Already Exists';
END IF;
COMMIT;
END;
END;
IF m=1 THEN
ROLLBACK;
SET msg='ERROR';
END IF;
SELECT msg as message;
END
I always get the error
MySQL said: #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;
IF m=1 THEN
ROLLBACK;
SET msg='ERROR';
END IF;
SELECT msg as message;' at line 23
Is there something obvious I am missing? I have been trying for some time to solve this with almost all the results to show the same error.
Any help will be highly appreciated.
Ok, I edited my own code and got the required result.
The changes I made was:
BEGIN
DECLARE unamec INT;
DECLARE emailc INT;
DECLARE m INT;
DECLARE msg VARCHAR(100);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
START TRANSACTION;
SET autocommit=0;
SELECT COUNT(*) INTO unamec FROM login WHERE uname=`#user`;
IF unamec=0 THEN
SELECT COUNT(*) INTO emailc FROM login WHERE email=#email;
IF emailc=0 THEN
INSERT INTO login (uname, hash, email, role) values(#user,MD5(#password),#email,'1');
SET msg='Successfully Registered';
ELSE
SET msg='Email Already Exists';
END IF;
ELSE
SET msg='Username Already Exists';
END IF;
COMMIT;
BEGIN
ROLLBACK;
SET msg='ERROR';
END;
SELECT msg as message;
END
If anyone get any other answer, still appreciate it.
Anyways, the above code is now working fine.
Related
DELIMITER ##
create trigger tra_Price after update on assets_cdn_charge for each row
begin
declare res int;
declare ids int;
declare idq int;
declare idt int;
set res = (select price from assets_cdn_charge where price = new.price);
set ids = (select id from assets_cdn_charge where price = new.price);
DECLARE cur CURSOR FOR SELECT id FROM assets_cdn_composite WHERE cdn_charge_id = ids;
open cur;
ins_loop:LOOP
fetch cur into idq;
declare curs cursor for select id from assets_cdn_traffic where domain_name_id = idq;
open curs;
ins1_loop:LOOP
fetch curs into idt;
update assets_cdn_traffic set cost = traffic * res where domain_namd_id = idt;
end LOOP;
close curs;
end LOOP;
close cur;
END; ##
when I run this code,I had get this error:
ERROR 1064 (42000): 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 'DECLARE cur CURSOR FOR SELECT id FROM
assets_cdn_composite WHERE cdn_charge_id =' at line 9
Probably because:
DECLARE is permitted only inside a BEGIN ... END compound statement
and must be at its start, before any other statements.
...so that line should likely be moved before the two set statements above that point.
I believe that you're going to have other trouble if that fixes that error, because I don't know what you expect that query to retrieve as idq is declared before that point, but is not set to any value?
=====
UPDATE:
Below is an example from a previous comment about the possibility to eliminate cursors altogether. Try this:
BEGIN
UPDATE assets_cdn_traffic
JOIN assets_cdn_composite ON assets_cdn_traffic.domain_name_id = assets_cdn_composite.cdn_charge_id
JOIN assets_cdn_charge ON assets_cdn_charge.id = assets_cdn_composite.cdn_charge_id
SET cost = traffic * NEW.price
WHERE assets_cdn_charge.id = NEW.id
END
However, I would try the update query separately before using in the trigger to make sure that it works as expected. Replace the NEW.price and the NEW.id with test values to verify the handling.
I try to create a stored procedure with an if statement within.
I copied from: https://dev.mysql.com/doc/refman/5.7/en/local-variable-scope.html
But I get the following error exact on the END IF; near '':
DROP PROCEDURE IF EXISTS `myProc`;
CREATE DEFINER=`root`#`%` PROCEDURE `myProc`(
IN in_userId int,
IN in_projectId int
)
BEGIN
DECLARE tmp_courseId int;
DECLARE done TINYINT DEFAULT 0;
DECLARE cursorProjectCourse CURSOR FOR SELECT CourseId FROM XC_PROJECT_COURSE where projectId = in_projectId ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cursorProjectCourse;
read_loop: LOOP
FETCH FROM cursorProjectCourse INTO tmp_courseId;
IF done = 1 THEN LEAVE read_loop;
END IF;
SELECT tmp_courseId, in_userId;
END LOOP;
CLOSE cursorProjectCourse;
END;
Has anyone an idea where I make a mistake?
Exact error message:
SQL Error [1064] [42000]: 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 19 SQL Error
MySQL Version:
5.5.46
Thanks for help!
I found the solution.
I have to set DELIMITER $$ at first statement and at the end DELIMITER ;
DELIMITER $$;
DROP PROCEDURE IF EXISTS `myProc`; $$
CREATE DEFINER=`root`#`%` PROCEDURE `myProc`(
IN in_userId int,
IN in_projectId int
)
BEGIN
DECLARE tmp_courseId int;
DECLARE done TINYINT DEFAULT 0;
DECLARE cursorProjectCourse CURSOR FOR SELECT CourseId FROM XC_PROJECT_COURSE where projectId = in_projectId ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cursorProjectCourse;
read_loop: LOOP
FETCH FROM cursorProjectCourse INTO tmp_courseId;
IF done = 1 THEN LEAVE read_loop;
END IF;
SELECT tmp_courseId, in_userId;
END LOOP;
CLOSE cursorProjectCourse;
END;$$
DELIMITER ;
It is important to set the keyword on the first position in line. If there is a blank on the first position, the error above will be thrown.
Well you are missing the loop label while ending loop. Change it to below
read_loop: LOOP
FETCH FROM cursorProjectCourse INTO tmp_courseId;
IF done = 1 THEN
LEAVE read_loop;
END IF;
END LOOP read_loop;
SELECT tmp_courseId, in_userId;
I can't see what is wrong with this syntax please help! I tried to look up the syntax from here
http://dev.mysql.com/doc/refman/5.5/en/declare-handler.html
DELIMITER $$
DROP PROCEDURE IF EXISTS `load_dimensions`$$
CREATE PROCEDURE `load_dimensions`( )
BEGIN
-- Declare variables to hold diagnostics area information
DECLARE code CHAR(5) DEFAULT '00000';
DECLARE msg TEXT;
DECLARE rows INT;
DECLARE result varchar(300);
-- Declare exception handler for failed insert
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
END;
INSERT dimtable(col)
SELECT col FROM extract;
IF code = '00000' THEN
GET DIAGNOSTICS rows = ROW_COUNT;
SET result = CONCAT('succeeded, row count = ',rows);
INSERT INTO etl_log (result)
SELECT CONCAT('Error',state,': ',msg);
ELSE
SET result = CONCAT('failed, error = ',code,', message = ',msg);
INSERT INTO etl_log (result)
SELECT CONCAT('Error',state,': ',msg);
END IF;
END $$
From the MySQL 5.5 reference pages
The GET DIAGNOSTICS statement is not supported until MySQL 5.6.
I run this code as a sql script from command line, and I get "you have an error in your SQL syntax" almost in all lines! Any ideas what is wrong here?
CREATE PROCEDURE updatemandate()
BEGIN
DECLARE _mandate_id BIGINT(20);
DECLARE _has_succesful_payment tinyint(1);
DECLARE done INT DEFAULT 0;
DECLARE cnt INT;
DECLARE mandateCursor CURSOR FOR Select mandate_id, has_succesful_payment From mandates;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN mandateCursor;
allmandates: LOOP
Fetch mandateCursor INTO _mandate_id, _has_succesful_payment;
IF done THEN LEAVE allmandates;
END IF;
Select COUNT(*) FROM payments WHERE mandate_id=_mandate_id AND status='OK' into cnt;
IF cnt>0 THEN
SET _has_succesful_payment=1;
END IF;
END LOOP allmandates;
CLOSE mandateCursor;
END
The ; character is the default delimiter, so when MySQL sees the first ; it thinks you are done. When you create a sproc, you need to declare a different delimiter character, like so:
DELIMITER $$
CREATE PROCEDURE updatemandate()
READS SQL DATA
BEGIN
DECLARE _mandate_id BIGINT(20);
DECLARE _has_succesful_payment tinyint(1);
DECLARE done INT DEFAULT 0;
DECLARE cnt INT;
DECLARE mandateCursor CURSOR FOR Select mandate_id, has_succesful_payment From mandates;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN mandateCursor;
allmandates: LOOP
Fetch mandateCursor INTO _mandate_id, _has_succesful_payment;
IF done THEN LEAVE allmandates;
END IF;
Select COUNT(*) FROM payment WHERE mandate_id=_mandate_id AND status='OK' into cnt;
IF cnt>0 THEN
SET _has_succesful_payment=1;
END IF;
END LOOP allmandates;
CLOSE mandateCursor;
END$$
DELIMITER ;
Also a good idea to add the READS SQL DATA to the sproc definition in case you need to support binary logging.
Have you tried putting delimiter // before the CREATE statement and change the last line with END //?
DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
BEGIN
ROLLBACK;
END;
START TRANSACTION;
UPDATE tbl_order SET TransactionID="abc" WHERE OrderID=1;
UPDATE tbl_order SET TransactionID="xyz" WHERE OrderID=;
UPDATE tbl_order SET TransactionID="zzz" WHERE OrderID=13;
COMMIT;
for some reason order 1 and 13 are filled without rollback and i get syntax error for the exit hadler.
Query: DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND BEGIN ROLLBACK
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 'DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
BEGIN
ROLLBACK' at line 1
can someone help me figure out what i'm doing wrong?
Thanks in advance
EDIT
UPDATE tbl_order SET TransactionID="xyz" WHERE OrderID=;
is intentional
I believe exit handlers can only be used in stored procedures. The documentation doesn't explicitly state this, but alludes to
Conditions may arise during stored program execution that require special handling
http://dev.mysql.com/doc/refman/5.1/en/condition-handling.html
I know this is quite outdated topic, but I encountered the same error when declaring my own procedure with transaction and error handling. The above procedure looks well, something OP didn't copy as it seems. The order is important and it should look like this:
Procedure declaration
Declaration of variables
ERROR HANDLING
Start transaction
Statements
Commit
End
In my case, it looks like this:
DELIMITER //
CREATE PROCEDURE pAddUser(IN _nick VARCHAR(30))
BEGIN
DECLARE doesUserExist BOOLEAN;
DECLARE accountCreationDate DATE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END;
START TRANSACTION;
SET doesUserExist = (SELECT EXISTS(SELECT * FROM tblUser WHERE nick=_nick));
IF NOT doesUserExist THEN
SET accountCreationDate = CURDATE();
INSERT INTO tblUser (nick, accountCreation) VALUES (_nick, CURDATE());
ELSE
SELECT CONCAT("Nick '", _nick, "' is in use!") AS 'Console output';
END IF;
COMMIT;
END;
//
DELIMITER ;