MySQL Inner cursor executes only one time - mysql

DELIMITER $$
CREATE PROCEDURE `remove_schedule_duplicate` ()
BEGIN
BLOCK1 : BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE schedule_id CHAR(36);
DECLARE gamePk INTEGER;
DECLARE keep_entry TINYINT(1);
DECLARE scheduleDuplicate CURSOR FOR SELECT game_pk FROM schedule where is_active = 1 group by game_pk,home_team_id,away_team_id,venue_id having count(game_pk) > 1 limit 2;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN scheduleDuplicate;
get_schedule_duplicate: LOOP
FETCH scheduleDuplicate INTO gamePk;
IF finished = 1 THEN
LEAVE get_schedule_duplicate;
END IF;
**BLOCK2 : BEGIN
DECLARE block_finished INTEGER DEFAULT 0;
DECLARE blockDuplicate CURSOR FOR SELECT id FROM schedule where game_pk = gamePk and is_active = 1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET block_finished = 1;
OPEN blockDuplicate;
block_schedule_duplicate: LOOP
FETCH blockDuplicate INTO schedule_id;
IF block_finished = 1 THEN
LEAVE block_schedule_duplicate;
END IF;
IF keep_entry = 0 THEN
UPDATE schedule set is_active = 0 where id = schedule_id;
END IF;
END LOOP block_schedule_duplicate;
CLOSE blockDuplicate;
END BLOCK2;**
END LOOP get_schedule_duplicate;
CLOSE scheduleDuplicate;
END BLOCK1;
END
$$
The problem is Innerloop first time execute well after that block_finished always be 1 so. always it quits the inner block.
How to resolve this issue. What i do ? Some one help me to resolve the issue.

I have Changed My Stored procedure like this:
DELIMITER $$
CREATE PROCEDURE `remove_schedule_duplicate`()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE schedule_id,temp CHAR(36) DEFAULT NULL;
DECLARE gamePk INTEGER;
DECLARE keep_entry TINYINT(1);
DECLARE scheduleDuplicate CURSOR FOR SELECT game_pk,id FROM schedule where game_pk in (SELECT game_pk FROM schedule where is_active = 1 group by game_pk,home_team_id,away_team_id,venue_id having count(game_pk) > 1) and is_active = 1 order by game_pk;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN scheduleDuplicate;
get_schedule_duplicate: LOOP
FETCH scheduleDuplicate INTO gamePk,schedule_id;
IF finished = 1 THEN
LEAVE get_schedule_duplicate;
END IF;
IF ((temp IS NULL) AND (gamePk IS NOT NULL)) OR ((temp IS NOT NULL) AND (temp <> gamePk)) THEN
SET temp = gamePk;
SET keep_entry = 1;
#ELSE IF temp IS NOT NULL AND temp = gamePk THEN
ELSE
SET keep_entry = 0;
END IF;
IF keep_entry = 0 THEN
UPDATE schedule set is_active = 0 where id = schedule_id;
END IF;
END LOOP get_schedule_duplicate;
CLOSE scheduleDuplicate;
END$$
DELIMITER ;

Related

MySQL Trigger only runs partially

I am trying to implement a trigger which transfers multiple records from 4 different tables to another set of 4 tables (denoted by the _history suffix) which have the same schema.
The trigger is as follows
DELIMITER //
create trigger shift_to_history
before update on event_ledger
for each row
begin
declare id,event_id,communication_number,communication_flag,slot_number,room_id,status_level,prev_status_level int default 0;
declare msg text;
declare req_date,end_date,start_date date;
declare purpose varchar(30);
declare misc_ledger_cursor cursor for select * from misc_ledger where event_id = old.event_id;
declare resource_communication_cursor cursor for select * from resource_communication where event_id = old.event_id;
declare slots_and_details_cursor cursor for select * from slots_and_details where event_id = old.event_id;
declare event_communication_cursor cursor for select * from event_communication where event_id = old.event_id;
insert into event_ledger_history values(old.event_id,old.event_name,old.description,old.username,old.start_date,old.end_date);
open misc_ledger_cursor;
begin
declare finished int default 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
misc_ledger_transfer: loop
fetch misc_ledger_cursor into event_id,communication_number,req_date,msg,communication_flag;
if finished = 1 then
leave misc_ledger_transfer;
end if;
insert into misc_ledger_history values (event_id,communication_number,req_date,msg,communication_flag);
end loop misc_ledger_transfer;
end;
close misc_ledger_cursor;
delete from misc_ledger where event_id = old.event_id;
open resource_communication_cursor;
begin
declare finished int default 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
resource_coms_transfer: loop
fetch resource_communication_cursor into event_id,msg,communication_number,communication_flag;
if finished = 1 then
leave resource_coms_transfer;
end if;
insert into resource_communication_history values (event_id,msg,communication_number,communication_flag);
delete from resource_communication where id = event_id;
end loop resource_coms_transfer;
end;
close resource_communication_cursor;
open event_communication_cursor;
begin
declare finished int default 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
event_coms_transfer: loop
fetch event_communication_cursor into event_id,msg,communication_number,communication_flag;
if finished = 1 then
leave event_coms_transfer;
end if;
insert into event_communication_history values (event_id,msg,communication_number,communication_flag);
end loop event_coms_transfer;
end;
close event_communication_cursor;
delete from event_communication where event_id = old.event_id;
open slots_and_details_cursor;
begin
declare finished int default 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
slots_and_details_transfer: loop
fetch slots_and_details_cursor into id,event_id,slot_number,room_id,start_date,end_date,status_level,prev_status_level,purpose,msg;
if finished = 1 then
leave slots_and_details_transfer;
end if;
insert into slots_and_details_history values (id,event_id,slot_number,room_id,start_date,end_date,status_level,prev_status_level,purpose,msg);
end loop slots_and_details_transfer;
end;
close slots_and_details_cursor;
delete from slots_and_details where event_id = old.event_id;
end//
DELIMITER ;
The Trigger runs only till
insert into event_ledger_history values(old.event_id,old.event_name,old.description,old.username,old.start_date,old.end_date);
After which it does not do anything.The MySQL Terminal gives a success message but the desired output is not achieved. ie The remaining history tables are till empty (the ones which use the cursor).
I reffered to MySQL stored procedure, handling multiple cursors and query results but did not receive favorable results.

Not able to run/execute MySQL Triggers

I am creating Trigger into Mysql Workbanch , but not able to create the trigger.
Can Anyone Help me For This.
DELIMITER $$
create TRIGGER Insert_Test
After Delete ON Test
FOR EACH ROW
BEGIN
START TRANSACTION;
DECLARE v_ID INT;
DECLARE v_Error TINYINT;
DECLARE v_AgentID INT;
SELECT v_Error = 0;
v_ID=Old.id;
BEGIN
DELETE Test2 WHERE id = SELECT id FROM Test where id=v_ID;
Rollback;
SET v_Error = 1;
END
IF v_Error = 0;
THEN
COMMIT;
ELSEIF
v_Error = 1;
THEN
ROLLBACK;
END IF;
END
DELIMITER ;
Sql server Trigger
ALTER TRIGGER [dbo].[tr_DelRecordTypeID] ON [dbo].[luRecordType] FOR DELETE
AS
SET NOCOUNT ON
BEGIN TRANSACTION
DECLARE #ID INT, #GroupTypeID INT, #Error BIT, #Msg VARCHAR(500)
SELECT #Error = 0
SELECT #ID = RecordTypeID FROM deleted
SELECT #GroupTypeID = 30
IF EXISTS ( SELECT g.GroupID
FROM luGroup g,
[luGroupDetail] gd
WHERE g.[GroupID] = gd.[GroupID]
AND g.[GroupTypeID] = #GroupTypeID
AND gd.[MemberID] = #ID )
BEGIN
DELETE [agAgent] WHERE [AgentID] = (SELECT TOP 1 AgentID FROM agAgentPayType)
Rollback transaction
SET #Error = 1
END
IF #Error = 0
BEGIN
COMMIT TRANSACTION
END
ELSE
IF #Error = 1
BEGIN
ROLLBACK TRANSACTION
END
This trigger which i am trying to achieve into mysql workbanch, please check
I shall Be thankful,
Thanks
Aman

MySQL Stored Procedure: Calling a Loop

I am new to MySQL Stored Procedure. I am writing a code that has a combination or cursors and CASEs.
I have a labeled loop in the cursor. Is it possible to call that labeled loop inside conditions of my CASEs
EDIT:
DROP PROCEDURE IF EXISTS ETOOLS_LATEST.SP_QueryTermsAndConditions;
COMMIT;
DELIMITER $$
CREATE PROCEDURE ETOOLS_LATEST.SP_QueryTermsAndConditions (
IN P_IN_ACCEPTED_BY VARCHAR(32),
OUT P_OUT_ACCEPTED_VERSION VARCHAR(10),
OUT P_OUT_CATEGORY VARCHAR(20),
OUT P_OUT_CURRENT_VERSION VARCHAR(10),
OUT P_OUT_FORCE_ACCEPT BOOLEAN
)
BEGIN
DECLARE noMoreRows BOOLEAN;
DECLARE loopCounter INT DEFAULT 0;
DECLARE rowCount INT DEFAULT 0;
DECLARE acceptedVersion INT(10);
DECLARE currentVersion INT(10);
DECLARE latestGeneral VARCHAR(10);
DECLARE latestBooking VARCHAR(10);
DECLARE curTnc CURSOR
FOR
SELECT a.version AS accepted_version,
a.category,
(
SELECT version
FROM apptermsandconditions c
WHERE is_latest IS True
AND c.category = a.category
) AS current_version
FROM ETOOLS_LATEST.apptermsandconditions a,
ETOOLS_LATEST.usertermsandconditions b
WHERE b.accepted_version = a.id
AND b.accepted_by = P_IN_ACCEPTED_BY;
DECLARE
CONTINUE HANDLER
FOR NOT FOUND
SET noMoreRows = TRUE;
SELECT VERSION
INTO latestGeneral
FROM ETOOLS_LATEST.AppTermsAndConditions
WHERE is_latest IS TRUE
AND CATEGORY = 'General';
SELECT VERSION
INTO latestBooking
FROM ETOOLS_LATEST.AppTermsAndConditions
WHERE is_latest IS TRUE
AND CATEGORY = 'Booking';
OPEN curTnc;
SELECT FOUND_ROWS()
INTO rowCount;
cursorLoop: LOOP
FETCH curTnc
INTO P_OUT_ACCEPTED_VERSION,
P_OUT_CATEGORY,
P_OUT_CURRENT_VERSION;
IF noMoreRows THEN
CLOSE curTnc;
LEAVE cursorLoop;
END IF;
IF P_OUT_ACCEPTED_VERSION <> P_OUT_CURRENT_VERSION THEN
SET P_OUT_FORCE_ACCEPT = 1;
ELSE
SET P_OUT_FORCE_ACCEPT = 0;
END IF;
SELECT P_OUT_ACCEPTED_VERSION,
P_OUT_CATEGORY,
P_OUT_CURRENT_VERSION,
P_OUT_FORCE_ACCEPT;
SET loopCounter = loopCounter + 1;
END LOOP cursorLoop;
CASE rowCount
WHEN 0
THEN
SELECT null, 'General', latestGeneral, 1;
SELECT null, 'Booking', latestBooking, 1;
WHEN 1
THEN
CASE P_OUT_CATEGORY
WHEN 'General'
THEN
SELECT null, 'Booking', latestBooking, 1;
WHEN 'Booking'
THEN
SELECT null, 'General', latestGeneral, 1;
END CASE;
WHEN 2
THEN
SELECT null;
END CASE;
END $$
DELIMITER ;
CALL SP_QueryTermsAndConditions('333333', #P_OUT_ACCEPTED_VERSION, #P_OUT_CATEGORY, #P_OUT_CURRENT_VERSION, #P_OUT_FORCE_ACCEPT);

splitting text data in mysql

i want to split my row something like this:
example:
id data
1 23#4#
2 2#4#5#
to be like this
id data
1 23
1 4
2 2
2 4
2 5
i have looking for this problem in stack overflow but the solution is not satisfaction me. please help me.
i try to make a store procedure in mysql, the code it's ok no error, but the result is not ok.
drop procedure if exists pecah_lokasi_sp;
create procedure pecah_lokasi_sp()
begin
DECLARE ii INT;
DECLARE ki varchar(255);
DECLARE ulang int DEFAULT 1;
DECLARE hasil varchar(255) DEFAULT '';
DECLARE selesai INT DEFAULT FALSE;
DECLARE kursor CURSOR FOR
SELECT id_iklan, lokasi_kerja_utama
FROM iklan_lowongan_tb
WHERE status = 'Aktif';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET selesai = TRUE;
DELETE FROM temp_lok_tb;
OPEN kursor;
read_loop: LOOP
FETCH kursor INTO ii, ki;
IF selesai THEN
LEAVE read_loop;
END IF;
WHILE (ulang < LENGTH(ki)) DO
IF SUBSTRING(ki, ulang, 1) <> '#' THEN
SET hasil = CONCAT(hasil, SUBSTRING(ki, ulang, 1));
ELSE
INSERT INTO temp_lok_tb (id_iklan, id_kota) VALUES(ii, hasil);
SET hasil = '';
END IF;
SET ulang = ulang+1;
END WHILE;
SET ulang = 1;
END LOOP read_loop;
CLOSE kursor;
select * from temp_lok_tb;
end;
i think i can solve my problem myself.
this is my revision code, the result is true.
drop procedure if exists pecah_lokasi_sp;
create procedure pecah_lokasi_sp()
begin
DECLARE ii INT;
DECLARE ki varchar(255);
DECLARE ulang int DEFAULT 1;
DECLARE hasil varchar(255) DEFAULT '';
DECLARE selesai INT DEFAULT FALSE;
DECLARE jmlkarakter int;
DECLARE kursor CURSOR FOR
SELECT id_iklan, lokasi_kerja_utama
FROM iklan_lowongan_tb
WHERE status = 'Aktif';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET selesai = TRUE;
DELETE FROM temp_lok_tb;
OPEN kursor;
read_loop: LOOP
FETCH kursor INTO ii, ki;
IF selesai THEN
LEAVE read_loop;
END IF;
SET jmlkarakter = LENGTH(ki) - LENGTH(REPLACE(ki, '#', '')) ;
WHILE (ulang <= jmlkarakter) DO
IF ulang = 1 THEN
INSERT INTO temp_lok_tb(id_iklan, id_kota) VALUES(ii, SUBSTRING_INDEX(ki,'#',1));
ELSE
INSERT INTO temp_lok_tb(id_iklan, id_kota) VALUES(ii, SUBSTRING_INDEX(SUBSTRING_INDEX(ki,'#', ulang),'#',-1));
END IF;
SET ulang = ulang+1;
END WHILE;
SET ulang = 1;
END LOOP read_loop;
CLOSE kursor;
select * from temp_lok_tb;
end;

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