Trigger is not working properly - mysql
I have create trigger for some condition but its through error.
Here is trigger code.
DELIMITER //
CREATE TRIGGER `getcrm`.`update_round_date` AFTER UPDATE ON `getcrm`.`vtiger_stockcheckcf`
FOR EACH ROW begin
DECLARE retribAn INTEGER DEFAULT 0;
DECLARE curEdate datetime;
DECLARE done INT DEFAULT 0;
DECLARE curTipo CURSOR FOR
SELECT a.*, b.*, c.* FROM vtiger_crmentity AS a, vtiger_stockcheck AS b,vtiger_stockcheckcf AS c WHERE a.crmid = b.stockcheckid AND a.crmid = c.stockcheckid AND c.cf_746 = 'Pending' AND a.setype='StockCheck';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
OPEN curTipo;
REPEAT
FETCH curTipo INTO retribAn;
IF NOT done THEN
set curEdate = NOW();
IF a.createdtime = curEdate AND c.cf_746 = Pending THEN
INSERT INTO vtiger_cancellationcf(scheckid,cf_1150,cf_1152,cf_1154,cf_1156,cf_1151,cf_1153,cf_1155,cf_1157,cf_1158,cf_1160,cf_1162,cf_1159,
cf_1161,cf_1163,cf_1203,cf_1178,cf_1180,cf_1182,cf_1184,cf_1186,cf_1178,cf_1180,cf_1182,cf_1184,cf_1186,cf_1179,cf_1181,
cf_1183,cf_1185,cf_1187,cf_1179,cf_1181,cf_1183,cf_1185,cf_1187,cf_1164,cf_1166,cf_1168,cf_1170,cf_1165,cf_1167,cf_1169,
cf_1171,cf_1173,cf_1176,cf_1177,cf_1172,cf_1174,cf_1175,cf_1188,cf_1189,cf_1190) values ('a.crmid','"c.cf_709"','"c.cf_711"','"c.cf_713"','"c.cf_715"','"c.cf_710"','"c.cf_712"','"c.cf_714"',
'"c.cf_716"','"c.cf_717"','"c.cf_719"','"c.cf_721"','"c.cf_718"','"c.cf_720"','"c.cf_844"','"c.cf_1079"','"c.cf_736"',
'"c.cf_738"','"c.cf_740"','"c.cf_742"','"c.cf_744"','"c.cf_737"','"c.cf_739"','"c.cf_741"','"c.cf_743"','"c.cf_745"',
'"c.cf_722"','"c.cf_724"','"c.cf_726"','"c.cf_723"','"c.cf_725"','"c.cf_727"','"c.cf_729"','"c.cf_731"','"c.cf_734"',
'"c.cf_735"','"c.cf_730"','"c.cf_732"','"c.cf_733"','"b.stockcheck"','"c.cf_746"','"c.cf_1080"','"c.cf_1081"');
insert into vtiger_cancellation (cancellationid,cancellation,scheckid) values ('a.crmid',' ','c.cf_709');
insert into vtiger_crmentity (crmid,smcreatorid,smownerid,modifiedby,setype,description,createdtime,modifiedtime,viewedtime,status,version,presence,deleted,label) values ('a.crmid','a.smcreatorid','a.smownerid','a.smcreatorid','Cancellation','','curEdate','curEdate','','','0','1','0','');
delete FROM vtiger_crmentity_seq where id='a.crmid';
insert into vtiger_crmentity_seq (id)values ('a.crmid');
END IF;
END IF;
UNTIL done END REPEAT;
CLOSE curTipo;
end
//
DELIMITER
Here is error when any changes on table.
1328 - Incorrect number of FETCH variables
Thanks for advance
I think the problem is here : FETCH curTipo INTO retribAn; your trying to fetch a complete row into a integer.
You should read more on CURSORS .
EXAMPLE:
DECLARE a CHAR(16);
DECLARE b INT;
DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
OPEN cur1;
FETCH cur1 INTO a, b;
Related
Looping mysql query inside trigger
Here is my trigger: DELIMITER | CREATE TRIGGER update_status_penjualan AFTER UPDATE ON penjualan FOR EACH ROW BEGIN DECLARE arrayresult = (SELECT * FROM rincian_penjualan WHERE id_penjualan = OLD.id) for ids in arrayresults UPDATE buku SET stok = stok + ids['jumlah']; WHERE noisbn = ids['noisbn']; endfor END; | DELIMITER ; I'v got many error, i think because my looping code is not right. Can anyone tell me how to fix it? Thanks ~
You could try with a cursor, something like this: DELIMITER | CREATE TRIGGER update_status_penjualan AFTER UPDATE ON penjualan FOR EACH ROW BEGIN declare jumlah_c int; declare noisbn_c int; declare done int; declare cur1 cursor for SELECT * FROM rincian_penjualan WHERE id_penjualan = OLD.id; declare continue handler for not found set done=1; set done = 0; open cur1; igmLoop: loop fetch cur1 into jumlah_c,noisbn_c; if done = 1 then leave igmLoop; end if; UPDATE buku SET stok = stok + jumlah_c WHERE noisbn = noisbn_c; end loop igmLoop; close cur1; END; | DELIMITER ;
couldnt compile mysql procedure for cursors
I am trying to use the below procedure to update a table but i could not compile the procedure. CREATE PROCEDURE `propmanage2016`.`test`() DECLARE CURSOR cur1 FOR SELECT unit_id, unit_code FROM t_units WHERE unit_projectid = 1; DECLARE done INT DEFAULT FALSE; DECLARE a INT; DECLARE b VARCHAR(200); DECLARE done INT DEFAULT FALSE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; BEGIN OPEN cur1; read_loop: LOOP FETCH cur1 INTO b , a ; IF done THEN LEAVE read_loop; END IF; UPDATE t_owner_resident SET or_unit = a WHERE unit_name = b; END LOOP; CLOSE cur1; END; please give some help
Sure you can't do it like this without the stored procedure? UPDATE t_owner_resident ow INNER JOIN t_units t set ow.unit_name = t.unit_code WHERE o.unit_name = t.unit_id and t.unit_projectid = 1 Note: I think a,b is mixed up in your SP, so please excuse if i've got the column names slightly mixed up too
Mysql Stored procedure with cursor
Mysql cursor issue? I have written a stored procedure which will travel's record from one table and insert those into 2-3 different tables using insert statements. Problem is that i am checking if record is not exists in table1 then I am inserting record from temptable to table1 ,table2 sequentially ,but the condition is having some problem i don't know it its always going into else part. Code sample is as follows: CREATE PROCEDURE `insertData`(In clientNo INT,In usedID INT) BEGIN declare mame varchar(100); declare address varchar(100); declare city varchar(50); declare IdentityNO1 varchar(20) declare cur1 cursor for select * from temptable; declare continue handler for not found set done=1; SET #clientNo = clientNO; SET #userID = userID; set done = 0; open cur1; igmLoop: loop fetch cur1 into Name,Address,City,IdentityNO1,clientNo; if done = 1 then leave igmLoop; end if; //If no record exists in some records table1,table2. IF ( (SELECT COUNT(*) FROM table1 WHERE IndentityNo=IdentityNo1 AND clientNo=#clientNo) < = 0) INSERT INTO table1 (Name,IdentityNO) VALUES (name,IdentityNO1); INSERT INTO table2 (Address,City) VALUES(address,city); ELSE INSERT INTO tblexceptional(Name,Address,City,IdentityNo) VALUES(name,address,city,IdentityNo1); end loop igmLoop; close cur1; END
There is no THEN nor END IF keywords, the procedure cannot compile. Check this link for proper syntax of IF statement: http://dev.mysql.com/doc/refman/5.7/en/if.html Use EXIST operator instead of (SELECT count(*)... ) <=0, read this link to know the reason: http://sqlblog.com/blogs/andrew_kelly/archive/2007/12/15/exists-vs-count-the-battle-never-ends.aspx IF EXISTS( SELECT null FROM table1 WHERE IndentityNo=IdentityNo1 AND clientNo=#clientNo ) THEN INSERT INTO table1 (Name,IdentityNO) VALUES (name,IdentityNO1); INSERT INTO table2 (Address,City) VALUES(address,city); ELSE INSERT INTO tblexceptional(Name,Address,City,IdentityNo) VALUES(name,address,city,IdentityNo1); END IF; I recommend using some prefixes for procedure arguments and variable names to avoid ambiguity, for example use p_ for parameters and v_ for variables. It's hard to guess, looking at this code, which name is a column name, a variable or a procedure parameter. This can lead to mistakes and errors. Avoid using SELECT * - this code will fail if someone will change the table structure. Explicitely list required columns in the cursor declaration: declare cur1 cursor for select name,Address,City,IdentityNO,clientNo from temptable; The corrected procedure might look like this: CREATE PROCEDURE `insertData`(In p_clientNo INT,In p_usedID INT) BEGIN declare v_name varchar(100); declare v_address varchar(100); declare v_city varchar(50); declare v_IdentityNO varchar(20) declare v_clientNo int declare cur1 cursor for select name,Address,City,IdentityNO,clientNo from temptable; declare continue handler for not found set done=1; set done = 0; open cur1; igmLoop: loop fetch cur1 into v_name,v_Address,v_City,v_IdentityNO,v_clientNo; if done = 1 then leave igmLoop; end if; //If no record exists in some records table1,table2. IF EXISTS( SELECT 1 FROM table1 WHERE IndentityNo = v_IdentityNo AND clientNo = v_clientNo) INSERT INTO table1 (Name,IdentityNO) VALUES (v_name,v_IdentityNO); INSERT INTO table2 (Address,City) VALUES(v_address,v_city); ELSE INSERT INTO tblexceptional(Name,Address,City,IdentityNo) VALUES(v_name,v_address,v_city,v_IdentityNo); END IF; end loop igmLoop; close cur1; END
Can an inner loop in a mysql procedure use the result of the outer loop
I have tried to create the following procedure in mysql PROCEDURE fix() BEGIN DECLARE event_id_ INT; DECLARE gate_number INT; DECLARE l_done INT DEFAULT 0; DECLARE curs_event_id CURSOR FOR SELECT DISTINCT event_id FROM history_15min; DECLARE curs_gate_number CURSOR FOR SELECT DISTINCT gate_number FROM history_15min WHERE event_id =event_id_; ( -- HERE IS THE PROBLEM - event_id_ IS BLANK THERE FOR THE INNER LOOP RETURNS NO RESULTS ....) DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_done=1; OPEN curs_event_id; event_loop : LOOP FETCH curs_event_id INTO event_id_; IF l_done=1 THEN LEAVE event_loop; END IF; OPEN curs_gate_number; gate_loop : LOOP FETCH curs_gate_number INTO gate_number; IF l_done=1 THEN LEAVE gate_loop; END IF; insert into t value ('1'); END LOOP gate_loop; CLOSE curs_gate_number; SET l_done=0; END LOOP event_loop; CLOSE curs_event_id; END Is there a way i can get the result from the first loop to be a variable in the second loop ??
Thank CHill60 , your link had the answer i was looking for here is the correct way to perform the nested loop : PROCEDURE fix() BLOCK1: BEGIN DECLARE colA_ INT; DECLARE l_done INT DEFAULT 0; DECLARE curs_colA CURSOR FOR SELECT DISTINCT colA FROM tableA; DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_done=1; OPEN curs_colA; first_loop : LOOP FETCH curs_colA INTO colA_; IF l_done=1 THEN LEAVE first_loop; END IF; BLOCK2: BEGIN DECLARE calB_ INT; DECLARE l_done INT DEFAULT 0; DECLARE curs_calB CURSOR FOR SELECT DISTINCT calB FROM tableB WHERE colA = colA_; DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_done=1; OPEN curs_calB; second_loop : LOOP FETCH curs_calB INTO calB_; IF l_done=1 THEN LEAVE second_loop; END IF; insert into tmp value ('1'); END LOOP second_loop; CLOSE curs_calB; SET l_done=0; END BLOCK2; END LOOP first_loop; CLOSE curs_colA; END BLOCK1
stored procedure with cursor in MySQL
Can I use Cursor with stored procedure in MySQL? And can I receive the output values from it?
Yes; CREATE PROCEDURE curdemo() BEGIN DECLARE done INT DEFAULT 0; DECLARE a CHAR(16); DECLARE b,c INT; DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1; DECLARE cur2 CURSOR FOR SELECT i FROM test.t2; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cur1; OPEN cur2; REPEAT FETCH cur1 INTO a, b; FETCH cur2 INTO c; IF NOT done THEN IF b < c THEN INSERT INTO test.t3 VALUES (a,b); ELSE INSERT INTO test.t3 VALUES (a,c); END IF; END IF; UNTIL done END REPEAT; CLOSE cur1; CLOSE cur2; END Example taken from the manual.