I have written a procedure in MySQL. I have set some conditions in my procedure. IF condition will not fill up then procedure will exit or full procedure will not execute. That means i want to stop to execute next lines of my procedure. In oracle i have used GOTO stop_level;. In MySQL i have seen that my full procedure have been executed. I want to declare a LEAVE label so that it can jump to LEAVE label & return with set message. Here is my MySQL procedure
CREATE PROCEDURE my_spring.`login_auth`(IN in_email varchar(100),
IN in_password varchar(100),
OUT user_id INT,
OUT out_code INT,
OUT out_message VARCHAR(1024))
BEGIN
BEGIN
IF in_email IS NULL OR in_email = ''
THEN
SET out_code = 1;
SET out_message = 'Please Enter Your Email.';
/* Exit here*/
END IF;
IF in_password IS NULL OR in_password = ''
THEN
SET out_code = 1;
SET out_message = 'Please Enter Your password.';
/* Exit here*/
END IF;
END ;
END;
I have used oracle GOTO function. When condition will not match then i call GOTO stop_label, it will jump to stop label not executing next line code. I want to handle my Procedure like oracle GOTO stop_level Here is stop_level code
<<stop_level>>
IF out_code = 0
THEN
COMMIT;
out_message := out_message;
ELSE
ROLLBACK;
out_code := 1;
out_message := out_message;
END IF;
How to do it?
MySQL doesn't have GOTO similar to Oracle, but they do have option to move control using LEAVE level (which you already mentioned). In your scenario, you could level your BEGIN block
leaveBlock:BEGIN
IF in_email IS NULL OR in_email = ''
THEN
SET out_code = 1;
SET out_message = 'Please Enter Your Email.';
LEAVE leaveBlock;
END IF;
IF in_password IS NULL OR in_password = ''
THEN
SET out_code = 1;
SET out_message = 'Please Enter Your password.';
LEAVE leaveBlock;
END IF;
END leaveBlock;
Related
Good evening,
Here is my stored procedure (compiled with succeed) :
DELIMITER $$
CREATE OR REPLACE PROCEDURE GetStringOptionList (IN p_infoTypeCode VARCHAR(15), IN p_language VARCHAR(1))
BEGIN
DECLARE v_infotype_code VARCHAR(15);
DECLARE v_infotype_description VARCHAR(50);
DECLARE v_stringopt_code VARCHAR(15);
DECLARE v_stringopt_description VARCHAR(50);
DECLARE v_noMoreRow INTEGER;
DECLARE cur_stringOptions
CURSOR FOR
SELECT infoType.code as 'infoTypeCode',
case when p_language = 'F' then infoType.frenchDescription
when p_language = 'E' then infoType.englishDescription
else ''
end as 'InfoTypeDescription',
stringOpt.code as 'StringOptionCode',
case when p_language = 'F' then stringOpt.frenchDescription
when p_language = 'E' then stringOpt.englishDescription
else ''
end as 'StringOptionDescription'
FROM InfoType infoType
JOIN StringOptionValue stringOptVal ON infoType.code = p_infoTypeCode AND infoType.code = stringOptVal.codeInfoType
JOIN StringOption stringOpt ON stringOptVal.codeStringOption = stringOpt.code;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_noMoreRow = 0;
SET v_noMoreRow = 1;
OPEN cur_stringOptions;
LOOPROWS: LOOP
IF v_noMoreRow = 0 THEN
CLOSE cur_stringOptions;
LEAVE LOOPROWS;
END IF;
FETCH NEXT FROM cur_stringOptions INTO v_infotype_code, v_infotype_description, v_stringopt_code, v_stringopt_description;
SELECT v_infotype_code, v_infotype_description, v_stringopt_code, v_stringopt_description;
END LOOP;
END$$
DELIMITER ;
When I compile my stored procedure under MySQL through PHPMyAdmin, no problem. But when I call my stored procedure like that :
call GetStringOptionList('EYESCOLOR', 'F')
I get the following error when I try to execute the stored procedure through PHPMyAdmin on http://localhost... :
Missing expression (near "ON" at position 25)
#2014 - Commands out of sync; you can't run this command now
I've tried through the program "mysql" in console mode. When I do "call GetStringOptionList("EYESCOLOR", "F")", I get blank line with an arrow "->". I don't know what does it mean.
Why ? Do you have a solution ?
I'm really struggling with this LOOP in my procedure. I can't understand what the error means. I guess anyone can just try to run this without any knowledge of the database...
DROP PROCEDURE IF EXISTS removeDuplicates;
DELIMITER $$
CREATE PROCEDURE removeDuplicates(str TEXT)
BEGIN
DECLARE temp_word TEXT;
DECLARE last_word TEXT;
DECLARE result TEXT;
DECLARE finished INT DEFAULT false;
DECLARE words_cursor CURSOR FOR
SELECT word FROM explosion;
DECLARE CONTINUE handler FOR NOT found
SET finished = true;
CALL explode(str);
DROP TABLE IF EXISTS temp_words;
CREATE TABLE temp_words (id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, t VARCHAR(100));
OPEN words_cursor;
loop_words: LOOP
FETCH words_cursor INTO temp_word;
IF finished THEN
LEAVE loop_words;
IF temp_word = "" THEN
SET result = CONCAT(result, temp_word, " ");
SET last_word = temp_word;
ELSEIF last_word = temp_word THEN
SET last_word = temp_word;
ELSE
INSERT INTO temp_words (t) VALUES (temp_word);
END IF;
END LOOP loop_words;
CLOSE words_cursor;
RETURN result;
END$$
DELIMITER ;
Any pointers would be gratefully received. The error I am getting is:
[ERROR in query 2] 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 'LOOP loop_words;
CLOSE words_cursor;
RETURN result;
END' at line 29
I'm sure it must be something simple, but I'll be damned if I can work it out.
Thanks, Chris
DROP PROCEDURE IF EXISTS removeDuplicates;
DELIMITER $$
CREATE PROCEDURE removeDuplicates(str TEXT , OUT OUT_STR_RESULT TEXT)
BEGIN
DECLARE temp_word TEXT;
DECLARE last_word TEXT;
DECLARE result TEXT;
DECLARE finished INT DEFAULT false;
DECLARE words_cursor CURSOR FOR
SELECT word FROM explosion;
DECLARE CONTINUE handler FOR NOT found
SET finished = true;
CALL explode(str);
DROP TABLE IF EXISTS temp_words;
CREATE TABLE temp_words (id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, t VARCHAR(100));
OPEN words_cursor;
loop_words: LOOP
FETCH words_cursor INTO temp_word;
IF finished THEN
LEAVE loop_words;
IF temp_word = "" THEN
SET result = CONCAT(result, temp_word, " ");
SET last_word = temp_word;
ELSEIF last_word = temp_word THEN
SET last_word = temp_word;
ELSE
INSERT INTO temp_words (t) VALUES (temp_word);
END IF;
END IF; -- i had made changes at this line.
END LOOP loop_words;
CLOSE words_cursor;
SET OUT_STR_RESULT =result;
-- RETURN result;
END$$
;
You missed one END IF.
One more thing: you can't put RETURN statement in procedure; it's only allowed in FUNCTION. Instead of that you can use OUT parameter for same.
Try above code.
I encountered a problem when trying to convert MSSQL code to MySQL.
My MSSQL code is:
CREATE PROCEDURE ProductGroupGenerationSettingsCheck
AS
declare #id bit , #result varchar(50);
SELECT #id = automaticProductIdGeneration
FROM tbl_Settings--)
if(#id =0)
begin
set #result='false'
end
else if (#id =1)
begin
set #result='true'
end
select #result
My MySQL code is:
delimiter //
create procedure ProductGroupGenerationSettingsCheck(p_id tinyint(1),p_result varchar(50))
begin
select p_id = automaticProductIdGeneration from tbl_Settings ;
if(p_id = 0)
begin
set p_result = 'false' ;
end
else if (p_id = 1)
begin
set p_result = 'true' ;
end
select p_result as 'result' ;
end //
delimiter ;
the error I get is:
#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 'begin set p_result = 'false' ; end else if (p_id = 1) begin set p_re' at line 5
What is wrong in my code?
delimiter //
create procedure ProductGroupGenerationSettingsCheck(IN p_id tinyint(1),IN p_result varchar(50)) /*specify what type of parameter it is, IN / OUT / INOUT*/
begin
select p_id := automaticProductIdGeneration from tbl_Settings ; /*use assignment operator := instead of comparison =*/
if(p_id = 0) then /*missing a then here*/
begin
set p_result = 'false' ;
/*don't end the if, when you still have an else if condition*/
else if (p_id = 1) then /*missing a then again*/
begin
set p_result = 'true' ;
end
end if; /*missing an if here*/
select p_result as 'result' ; /*you could also use an OUT parameter for this...anyway...*/
end //
delimiter ;
manual entry if statement
There are one error in the query at the forth line. Yo must use the next query.
select automaticProductIdGeneration into p_id from tbl_Settings;
It could be usefull if you post the entire error message. It shows you where is exactly the first problem.
For example, I've code like this:
...
PROCEDURE procedure1(... some parameters ...)
BEGIN
DECLARE l_xxx VARCHAR(5);
SET l_xxx = 'ERROR';
IF l_xxx = 'ERROR' THEN
-- in this section, I want to call 'foo' process below
END IF;
foo:BEGIN
-- Some process
END;
END;
Can I call the error:BEGIN in a stored procedure..?
You could create another stored procedure, and call it instead of GOTO-like command.
Try to do it using IF-THEN statement with a help of user variable.
For example:
DECLARE l_xxx VARCHAR(5);
SET l_xxx = 'ERROR';
SET #a = NULL;
IF l_xxx = 'ERROR' THEN
SET #a = 1; -- Set error flag
END IF;
IF #a IS NULL THEN
-- Some process, when there were no errors.
END IF;
IF #a = 1 THEN
BEGIN
-- Some process
END;
END IF;
I am trying to only execute a block of code if a variable exists. Here is a code snipit. Can you nest Begin...End statements in an IF block?
I've re-designed this several times. Suggestions?
delimiter //
drop trigger if exists example_trigger;//
create trigger example_trigger AFTER UPDATE on some_table for each row
BLOCK1: begin
-- check current status
DECLARE done BOOLEAN DEFAULT FALSE;
-- cap check
if (new.CURRENT_ALLOCATED >= new.TOTAL_ALLOWED_QTY) then
SET done = TRUE;
end if; -- cap check end
-- o
if (done != TRUE and new.O_KEY is not null and new.A_KEY is null) then
OBLOCK: begin
DECLARE done_o BOOLEAN DEFAULT FALSE;
DECLARE pd_nbr INT;
DECLARE no_more_rows BOOLEAN;
DECLARE cur_pd CURSOR FOR
select pd.STATUS_KEY
from PROD_DEL_V pd
join PROD_T p on pd.KEY_NBR = p.KEY_NBR
where pd.STATUS not in ('PU', 'EX')
and p.O_KEY = new.O_KEY;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET done_o = TRUE;
-- run updates
if (done_o != TRUE) then
-- open cursor
OPEN cur_pd;
-- loop start
loop_it: LOOP
FETCH cur_pd INTO pd_nbr;
-- exit loop if..
if no_more_rows = TRUE THEN
CLOSE cur_pd;
LEAVE loop_it;
end if;
INSERT INTO STATUS_TABLE (
STATUS_KEY
, STATUS
, NOTE_TXT
)
(
SELECT
PD.STATUS_KEY
, 'PU' AS STATUS
, concat('example_trigger - MAX has been reached or exceeded [TOTAL_ALLOWED_QTY = ',new.TOTAL_ALLOWED_QTY,' and CURRENT_ALLOCATED = ', new.CURRENT_ALLOCATED, ']') AS NOTE_TXT
FROM PROD_DEL_TABLE PD
WHERE PD.STATUS_KEY = pd_nbr
);
END LOOP loop_it;
end if; -- run updates end
end OBLOCK:; -- end block
end if; -- o
-- a
if (done != TRUE and new.O_KEY is null and new.A_KEY is not null) then
ABLOCK: begin
DECLARE done_a BOOLEAN DEFAULT FALSE;
DECLARE pd_nbr INT;
DECLARE no_more_rows BOOLEAN;
DECLARE cur_pd CURSOR FOR
select pd.STATUS_KEY
from PROD_DEL_V pd
join PROD_T p on pd.KEY_NBR = p.KEY_NBR
join A_O_T a on a.O_KEY = p.O_KEY
where pd.STATUS not in ('PU', 'EX')
and a.A_KEY = new.A_KEY;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET done_a = TRUE;
-- run updates
if (done_a != TRUE) then
-- open cursor
OPEN cur_pd;
-- loop start
loop_it: LOOP
FETCH cur_pd INTO pd_nbr;
-- exit loop if..
if no_more_rows = TRUE THEN
CLOSE cur_pd;
LEAVE loop_it;
end if;
INSERT INTO STATUS_TABLE (
STATUS_KEY
, STATUS
, NOTE_TXT
)
(
SELECT
PD.STATUS_KEY
, 'PU' AS STATUS
, concat('example_trigger - MAX has been reached or exceeded [TOTAL_ALLOWED_QTY = ',new.TOTAL_ALLOWED_QTY,' and CURRENT_ALLOCATED = ', new.CURRENT_ALLOCATED, ']' AS NOTE_TXT
FROM PROD_DEL_TABLE PD
WHERE PD.STATUS_KEY = pd_nbr
);
END LOOP loop_it;
end if; -- run updates end
end ABLOCK; -- end block
end if; -- a
end BLOCK1; -- end large block
//
delimiter ;
What is the problem with IF and BEGIN...END clause? Take a look at this simple example -
CREATE PROCEDURE procedure1(IN Param1 VARCHAR(255))
BEGIN
IF Param1 = 1 THEN
BEGIN
DECLARE i INT;
-- do something
END;
ELSE
BEGIN
DECLARE i INT;
-- do something
END;
END IF;
END