I have created a Trigger after INSERT on the table AcademicYearTermLevel which uses a cursor value fetched from another query. I want to use each cursor value in a while loop and insert rows into table SubjectYearTermLevel.
DROP TRIGGER IF EXISTS after_academicyearterm_insert
DELIMITER $$
CREATE TRIGGER after_academicyearterm_insert
AFTER INSERT
ON AcademicYearTerm
FOR EACH ROW
BEGIN
DECLARE temp INT;
DECLARE subj_done, form_done BOOLEAN DEFAULT FALSE;
DECLARE s_id INT;
DECLARE curSubject CURSOR FOR SELECT subject_id FROM Subject;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET subj_done = TRUE;
SET temp = 1;
OPEN curSubject;
cur_subject_loop: LOOP
FETCH FROM curSubject INTO s_id;
IF subj_done THEN
CLOSE curSubject;
LEAVE cur_subject_loop;
END IF;
WHILE temp <= 6 DO
INSERT INTO SubjectYearTermLevel VALUES (NULL, s_id, NEW.yearTerm_id, temp);
SET temp = temp + 1;
END WHILE
END LOOP cur_subject_loop;
END$$
DELIMITER ;
However the problem is that the cursor only seems to fetch one value from the SELECT query
Silly mistake, I SET temp = 1; outside the FETCH, and hence after the first cursor value, the while loop never ran.
-- SET temp = 1;
OPEN curSubject;
cur_subject_loop: LOOP
FETCH FROM curSubject INTO s_id;
SET temp = 1;
IF subj_done THEN
CLOSE curSubject;
LEAVE cur_subject_loop;
END IF;
1_to_6_temp: WHILE temp <= 6 DO
INSERT INTO SubjectYearTermLevel VALUES (NULL, s_id, NEW.yearTerm_id, temp, -1);
SET temp = temp + 1;
END WHILE 1_to_6_temp;
-- CLOSE curSubject;
END LOOP cur_subject_loop;
Related
I'm new to Mysql Stored Procedures.
Tring to return rows in a stored procedure after a LOOP.
Here's my code
BEGIN
DECLARE date_SD date;
DECLARE c_stack CURSOR FOR
select SD from t4 where date(SD) >= "2022-05-01" and date(SD)<= "2022-05-30" group by SD;
DROP TEMPORARY TABLE IF EXISTS final_result;
CREATE TEMPORARY TABLE final_result LIKE templaedb.temp_table;
OPEN c_stack;
read_loop: LOOP
FETCH c_stack INTO date_SD;
INSERT INTO final_result VALUES ('first','140','2022-05-06','','1','2','3','4','5');
INSERT INTO final_result VALUES ('last','500','2022-05-06','','11','12','13','14','15');
END LOOP read_loop;
CLOSE c_stack;
select 'Print Test';
select * from final_result;
END
Select statement at last of the Stored Procedure is not working.
Try this
DECLARE date_SD date;
DECLARE c_stack CURSOR FOR
select SD from t4 where date(SD) >= "2022-05-01" and date(SD)<= "2022-05-30" group by SD;
/* add this*/ DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
DROP TEMPORARY TABLE IF EXISTS final_result;
CREATE TEMPORARY TABLE final_result LIKE templaedb.temp_table;
OPEN c_stack;
read_loop: LOOP
FETCH c_stack INTO date_SD;
/* must include*/
IF done = 1 THEN
LEAVE read_loop;
END IF;
/* must include*/
INSERT INTO final_result VALUES ('first','140','2022-05-06','','1','2','3','4','5');
INSERT INTO final_result VALUES ('last','500','2022-05-06','','11','12','13','14','15');
END LOOP read_loop;
CLOSE c_stack;
select * from final_result;
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.
When updating data in database tables, I need to write to a separate table: table name, change date, old column value, new column value.
I wrote a trigger:
CREATE TRIGGER `user_update_trigger`
AFTER UPDATE ON `users`
FOR EACH ROW
BEGIN
DECLARE done int default false;
DECLARE col_name CHAR(255);
DECLARE counter INTEGER(11);
DECLARE column_cursor cursor for SELECT `column_name`
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA`='test'
AND `TABLE_NAME`='users';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
open column_cursor;
myloop: loop
fetch column_cursor into col_name;
if done then
leave myloop;
end if;
/*SET #old_val = OLD.{{col_name}}; <------ HERE */
/*SET #new_val = NEW.{{col_name}};<------ HERE */
if #old_val <> #new_val then
/*INSERT INTO `logs` ....*/
end if;
end loop;
close column_cursor;
END;
I need to get the value from OLD and NEW.
But column name is in the variable col_name.
I tried:
SET #old_q = CONCAT('OLD.', col_name);
SET #new_q = CONCAT('NEW.', col_name);
PREPARE old_prepare_query FROM #old_q;
PREPARE new_prepare_query FROM #new_q;
EXECUTE old_prepare_query USING #old_val;
EXECUTE new_prepare_query USING #new_val;
But I got an error:
Error Code: 1336. Dynamic SQL is not allowed in stored function or trigger
I made a database migration from Postgres to MySQL, now I can't able to convert a trigger to this new database engine. Postgres trigger function below:
CREATE OR REPLACE FUNCTION ins_stk_dt_in_lgr_frm_purchase_entry()
RETURNS trigger AS
$BODY$
declare
stocid integer;
rec record;
rec1 record;
dt date;
begin
dt = now()::date;
for rec in
select a.trnpurenthdid,c.productid,b.prodserialno as serial_no,b.prodbatchno,b.qty as qtyrecd,a.uom,b.warranty_date,b.exp_date from trnpurentdet a
join trnpurentdet2 b on a.trnpurentdetid = b.trnpurentdet1id
join mstproductdet c on c.productdetid=a.productpetid
where trnpurentdet2id = new.trnpurentdet2id
loop
if(rec.serial_no <> '') then
insert into stock_leger (leger_date,io_flag,transtype,referdoctno,product_id,serialno,systemremark,qty,uom,expiry_date,warrenty_date) values (dt,1,'PE',rec.trnpurenthdid,rec.productid,rec.serial_no,'PUR_ENT',rec.qtyrecd,rec.uom,rec.exp_date,rec.warranty_date);
end if;
if(rec.prodbatchno <> '') then
insert into stock_leger (leger_date,io_flag,transtype,referdoctno,product_id,batchno,systemremark,qty,uom,expiry_date,warrenty_date) values (dt,1,'PE',rec.trnpurenthdid,rec.productid,rec.prodbatchno,'PUR_ENT',rec.qtyrecd,rec.uom,rec.exp_date,rec.warranty_date);
end if;
end loop;
return new;
end;
$BODY$;
How to change this trigger as mysql format?
DELIMITER //
CREATE TRIGGER ins_stk_dt_in_lgr_frm_purchase_entry
AFTER INSERT on trnpurentdet2 for each row BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE a1,b1,e1,f1 INT;
DECLARE c1,d1 varchar(50);
DECLARE dt,g1,h1 date;
DECLARE rec CURSOR FOR SELECT a.trnpurenthdid,c.productid,b.prodserialno as serial_no,b.prodbatchno,b.qty as qtyrecd,a.uom,b.warranty_date,b.exp_date from trnpurentdet a
join trnpurentdet2 b on a.trnpurentdetid = b.trnpurentdet1id
join mstproductdet c on c.productdetid=a.productpetid
where trnpurentdet2id = NEW.trnpurentdet2id;
set dt = curdate();
OPEN rec;
ins_loop: LOOP
FETCH rec INTO a1, b1, c1,d1,e1,f1,g1,h1;
IF done THEN
LEAVE ins_loop;
END IF;
IF(c1 <> '') THEN
INSERT into stock_leger (leger_date,io_flag,transtype,referdoctno,product_id,serialno,systemremark,qty,uom,expiry_date,warrenty_date) values (dt,1,'PE',a1,b1,c1,'PUR_ENT',e1,f1,g1,h1);
ELSE
INSERT into stock_leger (leger_date,io_flag,transtype,referdoctno,product_id,batchno,systemremark,qty,uom,expiry_date,warrenty_date) values (dt,1,'PE',a1,b1,d1,'PUR_ENT',e1,f1,g1,h1);
END IF;
END LOOP;
CLOSE rec;
END;//
DELIMITER;
i created an event that execute one time per month. Three tables are important here, Cuota(fee), Alumno(studient) and CuotaxAlumno(fee per studient).
My objective is create a row in table Cuota(fee) one time per month and then with that fee create a payment row for every studient (in table CuotaxAlumno).
I having syntax error in te FETCH line, line 19, and i don't find the problem. i will appreciate the help.
IS WORKING NOW. CODE UPDATED 13-04-2017 Thanks!
DELIMITER $$
CREATE PROCEDURE crearCuotas()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE referenciaMonto INT;
DECLARE referenciaAlumno INT;
DECLARE referenciaCuota INT;
DECLARE fecha DATE;
DECLARE cursorAlumno CURSOR FOR SELECT idAlumno FROM alumno WHERE idEstado=1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET referenciaMonto = (SELECT idMontoCuota FROM montocuota ORDER BY idMontoCuota DESC LIMIT 1);
SET fecha = CURDATE();
INSERT INTO cuota (idMontoCuota, fecha) VALUES(referenciaMonto, fecha);
SET referenciaCuota = (SELECT idCuota FROM cuota ORDER BY idCuota DESC LIMIT 1);
OPEN cursorAlumno;
fetch_loop: LOOP
FETCH cursorAlumno INTO referenciaAlumno;
IF done THEN
LEAVE fetch_loop;
END IF;
INSERT INTO cuotaxalumno(idAlumno, idCuota, idEstado) VALUES(referenciaAlumno, referenciaCuota, 5);
END LOOP;
CLOSE cursorAlumno;
END;
DELIMITER ;
You need to add a loop label:
CREATE PROCEDURE crearCuotas()
BEGIN
/* yada */
OPEN cursorAlumno;
fetch_loop: LOOP
FETCH cursorAlumno INTO referenciaAlumno;
IF done THEN
LEAVE fetch_loop;
END IF;
INSERT INTO cuotaxalumno (idAlumno, idCuota, idEstado)
VALUES (referenciaAlumno, referenciaCuota, 5);
END LOOP;
CLOSE cursorAlumno;
END;
This is because while the label is not required for creating a loop, it is required for the leave statement.