MySQL - Jump to "foo:Begin" in Stored Procedure - mysql

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;

Related

How to stop execute full stored procedure in MySQL?

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;

MySQL stored procedure causes error

Can someone kindly tell me where I'm wrong ?
This procedure returns an error near
#recuperato = #recuperato - saldofattura;
I mistake to update the variable #recuperato?
Thanks to all
DELIMITER //
DROP PROCEDURE IF EXISTS fatture_lettere_retail//
CREATE PROCEDURE fatture_lettere_retail (idcontratto INT(11))
BEGIN
DECLARE finito INT default 0;
DECLARE idfattura INT default 0;
DECLARE saldofattura DECIMAL(10,2);
DECLARE cur1 CURSOR FOR SELECT idfattura,saldofattura FROM fatture_lettere_isa;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'
SET finito = 1;
SET #recuperato=(SELECT SUM(valorea)-SUM(valorer) FROM ImportiContratto WHERE idcontratto=idcontratto AND idimporto=1);
ciclo: LOOP
SET finito = 0;
FETCH cur1 INTO idfattura,saldofattura;
IF finito THEN
LEAVE ciclo;
END IF;
IF (#recuperato-saldofattura>=0) THEN
#recuperato = #recuperato-saldofattura;
DELETE FROM fatture_lettere_isa WHERE idfattura=idfattura;
ELSE
UPDATE fatture_lettere_isa SET saldofattura=saldofattura-#recuperato;
LEAVE ciclo;
END IF;
END LOOP ciclo;
CLOSE cur1;
END; //
DELIMITER;
Add the SET keyword at the beginning of the row in question:
SET #recuperato = #recuperato-saldofattura;
You have to write SET keyword to assign value to variable "#recuperato" as follow:
SET #recuperato = #recuperato-saldofattura;

Mysql - How to split text variable in stored procedure

I have a MySQL variable as below.
DECLARE str TEXT DEFAULT '2014-01-02 13:00:00|2014-02-04 12:59:59#0#2014-02-04 13:00:00|2014-03-04 12:59:59#0#2014-03-04 13:00:00|2014-04-02 13:59:59#0#2014-04-02 14:00:00|2014-05-02 14:59:59#0#2014-05-02 15:00:00|2014-06-03 14:59:59';
I want to break this whole string first by using the separator #0# and from the results break the string using separator |.
I have tried MySQL split_str function but I am not able to do it.
Its giving me the error split_str does not exist.
Please suggest some other way to do this.
Finally i have resolved my problem using below procedure.
I am able to solve it using temporary table and procedure. I am no more using mysql variable for this. We can call the procedure as below....
CALL SplitString('2014-01-02 13:00:00|2014-02-04 12:59:59#0#2014-02-04 13:00:00|2014-03-04 12:59:59#0#2014-03-04 13:00:00|2014-04-02 13:59:59#0#2014-04-02 14:00:00|2014-05-02 14:59:59#0#2014-05-02 15:00:00|2014-06-03 14:59:59', '#0#', 'tblindex');
Here tblindex is temporary table i have used.
My procedure is below....
DELIMITER $$
DROP PROCEDURE IF EXISTS `SplitString`$$
CREATE PROCEDURE `SplitString`( IN input TEXT,IN delm VARCHAR(10),tblnm varchar(50))
BEGIN
DECLARE cur_position INT DEFAULT 1 ;
DECLARE remainder TEXT;
DECLARE cur_string VARCHAR(1000);
DECLARE delm_length TINYINT UNSIGNED;
set #sql_drop = concat("DROP TABLE IF EXISTS ",tblnm);
prepare st_drop from #sql_drop;
execute st_drop;
set #sql_create = concat("CREATE TEMPORARY TABLE ",tblnm," (value VARCHAR(2000) NOT NULL ) ENGINE=MEMORY;");
prepare st_create from #sql_create;
execute st_create;
SET remainder = input;
SET delm_length = CHAR_LENGTH(delm);
WHILE CHAR_LENGTH(remainder) > 0 AND cur_position > 0
DO
SET cur_position = INSTR(remainder, delm);
IF cur_position = 0 THEN
SET cur_string = remainder;
ELSE
SET cur_string = LEFT(remainder, cur_position - 1);
END IF;
-- select cur_string;
IF TRIM(cur_string) != '' THEN
set #sql_insert = concat("INSERT INTO ",tblnm," VALUES ('",cur_string,"');");
prepare st_insert from #sql_insert;
execute st_insert;
END IF;
SET remainder = SUBSTRING(remainder, cur_position + delm_length);
END WHILE;
END$$
DELIMITER ;

Mysql procedure: nesting begin statements in conditional blocks

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

How to replace a string with another in whole tables in a mysql database

I want to replace a string with another in full database. Assume database name is "A" and it contains 101 tables. I want to change "subhojit" to "jeet" in all table's column if it contains "subhojit".
Is it possible in MySql?
Need to write procedure?
Please reply.
update thetable set thecol = replace(thecol, 'subhojit', 'jeet')
where thecol like '%subhojit%';
From here.
This is a bit rough and ready (exception handling for example). But hopefully you can tidy it up for your own purposes:
DELIMITER $$
CREATE PROCEDURE `replace_value_in_all_cols`(IN i_schema varchar(250),IN i_fromVal varchar(250),IN i_toVal varchar(250), OUT o_errMessage varchar(250))
BEGIN
ALL_TEXT_COLUMNS : BEGIN
DECLARE noMoreRows boolean;
DECLARE db varchar(250);
DECLARE tbl varchar(250);
DECLARE col varchar(250);
DECLARE allTextCols CURSOR FOR
select c.table_schema,c.table_name,c.column_name
from information_schema.columns c
where c.table_schema = i_schema
and lower(data_type) in ('char','text','varchar');
DECLARE EXIT HANDLER for SQLEXCEPTION set o_errMessage := "Some error message";
declare continue handler for not found set noMoreRows := true;
open allTextCols;
UPDATE_LOOP : loop
fetch allTextCols
into db,tbl,col;
if noMoreRows then
close allTextCols;
leave UPDATE_LOOP;
end if;
SET #update_stmt:=CONCAT("UPDATE ",db,".",tbl," SET ",col," = replace(",col,",'",i_fromVal,"','",i_toVal,"');");
PREPARE update_stmt FROM #update_stmt;
EXECUTE update_stmt;
DEALLOCATE PREPARE update_stmt;
end loop UPDATE_LOOP;
END ALL_TEXT_COLUMNS;
END$$
DELIMITER ;
Then you can do something like:
call `replace_value_in_all_cols`("A",'subhojit','jeet', #err);