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.