Update in mysql trigger not working - mysql

I'm creating a trigger to execute after an insert is done into my checkin table but my update statement is not working
DELIMITER $$
DROP TRIGGER IF EXISTS checkins_AINS$$
CREATE TRIGGER `checkins_AINS` AFTER INSERT ON `checkins` FOR EACH ROW
BEGIN
DECLARE client_id INT;
DECLARE duplicate_record INTEGER DEFAULT 0;
DECLARE bpoints INT;
DECLARE business_id INT;
DECLARE CONTINUE HANDLER FOR 1062 SET duplicate_record = 1;
SELECT checkinPoints, id INTO bpoints, business_id FROM businesses WHERE id = new.venue_id;
INSERT INTO clients_checkins_summary(client_id, venue_id, first_checkin, last_checkin,visits)
VALUES(new.client_id, new.venue_id, new.createAt, new.createAt,1);
INSERT INTO clients_points_summary(client_id, business_id,current_points)
VALUES(new.client_id, business_id,bpoints);
IF duplicate_record = 1
THEN
UPDATE clients_checkins_summary
SET last_checkin = new.createAt,
visits = visits + 1
WHERE client_id = new.client_id and venue_id = new.venue_id;
UPDATE clients_points_summary
SET current_points = current_points + bpoints
WHERE client_id = new.client_id and business_id = business_id;
END IF;
END$$
DELIMITER ;
Inserting:
insert into checkins(client_id,venue_id,points,createAt,updateAt)
values (52,19,1,now(),now());
for the first time works fine but when the case of update is trigger is entering into the if but is not update the value.
I trace the variables into a table and all the values are correct but update is not been updating anything.
I missing something?

am I missing something?
Possibly this
UPDATE clients_points_summary
SET current_points = current_points + bpoints
WHERE client_id = new.client_id and business_id = business_id;
The problem here is that your local variable business_id and the column name clients_points_summary.business_id are ambiguous. You could disambiguate as follows:
UPDATE clients_points_summary cps
SET cps.current_points = cps.current_points + bpoints
WHERE cps.client_id = new.client_id and cps.business_id = business_id;

Related

Dynamic name tablŠµ in trigger

There is a trigger that copies columns from one table to another. How do I assign a table name to a dynamic variable #nametable?
Every day the name of the table changes depending on the current date.
USE dbo;
DROP TRIGGER IF EXISTS `update_test`;
GO
DELIMITER |
CREATE TRIGGER `update_test` AFTER INSERT ON `hello_send`
FOR EACH ROW
BEGIN
DECLARE nametable VARCHAR(128);
SET #nametable =(DATE_FORMAT(NOW(),"%d%m%Y_v"));
INSERT INTO `dbo`.`nametable` SET
`TIME_` =NEW.`recorded`,
`P1` = NEW.`value1`
ON DUPLICATE KEY UPDATE
`TIME_` = NEW.`recorded`,
`P1` = NEW.`value1`;
END;
Have error ERROR 1146: Table 'dbo.nametable' doesn't exist
I decided to do so as a temporary solution:
CREATE TRIGGER `update_test` AFTER INSERT ON `hello_send`
FOR EACH ROW
BEGIN
SET #dateNameTableNOW =(DATE_FORMAT(NOW(),"%d%m%Y_v"));
SET #dateNameTableSELECT1 = '06122017_v';
SET #dateNameTableSELECT2 = '07122017_v';
IF(#dateNameTableNOW = #dateNameTableSELECT1) THEN
INSERT INTO dbo.06122017_v SET TIME_=NEW.recorded, P1 = NEW.value1 ON DUPLICATE KEY UPDATE TIME_ = NEW.recorded, P1 = NEW.value1;
END IF;
IF(#dateNameTableNOW = #dateNameTableSELECT2) THEN
INSERT INTO dbo.07122017_v SET TIME_=NEW.recorded, P1 = NEW.value1 ON DUPLICATE KEY UPDATE TIME_ = NEW.recorded, P1 = NEW.value1;
END IF;
END;

MySQL Trigger updates all rows even if a distinct where clause is given

Refer to the following trigger,
create trigger trigger_update_rows after insert on transaction for each row
DECLARE tr_type VARCHAR(15);
DECLARE tr_op VARCHAR(10);
DECLARE tr_amt FLOAT(8,2);
DECLARE tr_qnt INTEGER;
DECLARE item_id INTEGER;
SET tr_type = NEW.TRANSACTION_TYPE;
SET tr_op = (SELECT TRANSACTION_TYPE_OPERATION FROM transaction_type WHERE
TRANSACTION_TYPE_NAME=tr_type limit 1);
SET tr_amt = NEW.TRANSACTION_AMOUNT;
SET tr_qnt = NEW.QUANTITY;
SET item_id = NEW.ITEM_ID;
IF tr_op = 'ADD' THEN
update item set QUANTITY_AVAILABLE=QUANTITY_AVAILABLE-
tr_qnt,QUANTITY_SOLD=QUANTITY_SOLD+tr_qnt,AVAILABLE_GOODS_VALUE =
AVAILABLE_GOODS_VALUE - tr_amt,SOLD_GOODS_VALUE=SOLD_GOODS_VALUE+tr_amt
where ITEM_ID=item_id;
ELSEIF tr_op = 'SUBTRACT' THEN
update item set QUANTITY_AVAILABLE=QUANTITY_AVAILABLE+tr_qnt,QUANTITY_BOUGHT=QUANTITY_BOUGHT+tr_qnt,AVAILABLE_GOODS_VALUE=AVAILABLE_GOODS_VALUE+tr_amt,BOUGHT_GOODS_VALUE=BOUGHT_GOODS_VALUE+tr_amt where ITEM_ID=item_id;
END IF;
END
ITEM_ID is a primary key in the table item and the following is the transaction row inserted
insert into transaction(TRANSACTION_DATE,TRANSACTION_TYPE,ITEM_ID,QUANTITY,TRANSACTION_AMOUNT,ACCOUNT_ID,BUYER,SELLER) values ('2017-08-12','BUY',2,5,500.00,3,1,2);
What is making the above trigger update all rows in item instead following the where clause
You problem is:
where ITEM_ID = item_id;
You may think that one of the item_ids is somehow connected to the variable. It is not.
Rename the variable to something like v_item_id and then use:
where item_id = v_item_id

declaring variable inside mysql stored procedure

we are trying to declare a variable inside mysql stored procedure that has transaction implemented in it. but it seems to be giving a syntax error :
following is the syntax of the stored procedure:
CREATE PROCEDURE `sp_MarkAppointmentRefferal`(
p_AppId bigint,
p_NewLocation bigint,
p_userId bigint,
p_ReferralReason varchar(500),
p_NewLocationName varchar(100)
)
begin
declare v_OldLocation int default 0;
set v_OldLocation = (select LocationId FROM appointments where iAppID = p_AppId limit 1 );
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
select -1;
END;
START TRANSACTION;
update table
set is_referred = 1,
referred_timestamp = now(),
referral_reason = p_ReferralReason
where iAppID = p_AppId
limit 1;
-- create a new appointment for the new referred location..
insert into appointments
(vAppName, vAppType, dAppDate, vCell, iPatID, iAppStatus, iuserid, iActive,
dInsertDate, iHSID, daily_ticket_no, LocationId, visit_id, encounter_id, ReferredFrom,ReferredOPDName, opd_name )
select vAppName, vAppType, now(), vCell, iPatID, iAppStatus, p_userId,
1, now(), iHSID, fn_GenerateNextAppointmentTicket(now(),p_NewLocation) , p_NewLocation, visit_id, encounter_id+1,
(select LocationId FROM appointments where iAppID = p_AppId limit 1),
(select OPD_Name FROM appointments where iAppID = p_AppId limit 1), p_NewLocationName
FROM appointments
where iAppID = p_AppId limit 1;
select LAST_INSERT_ID();
COMMIT;
end;
the syntax checker is saying that declare command is not valid here.
have also tried to place this inside the transaction clause and similar error shows up ..
any help is appreciated..
All declare statements should be at the top of the stored procedure body. Moving DECLARE EXIT HANDLER before the SET statement should fix the problem.

Insert into change value if duplicate entry

I have this sql query:
INSERT INTO my_table
SELECT id, name, type
FROM other_table
I have this row: 1,bob,male
And I try insert: 1,bob,male
So, I have a duplicate entry error and I want change my insert value with an increment by one so after I would have two rows:
bob,male <=NOT UPDATED
bob,male
I don't want update the existing row, if I have a duplicate entry error. The insert increments the id value. So, I think ON DUPLICATE KEY isn't the solution.
UPDATE:
If I use a trigger like this:
DELIMITER |
CREATE TRIGGER incremente_primary BEFORE INSERT ON my_table FOR EACH ROW
BEGIN
IF( EXISTS( SELECT * FROM my_table )) THEN
SET NEW.id = NEW.id + 1;
END IF;
END |
DELIMITER ;
It doesn't work because a trigger can read only one line.
As per your requirement, you need to set auto_increment property for your id and then just insert other columns except id, so that it can be auto_increment like below-
INSERT INTO my_table (name,type)
SELECT name, type
FROM other_table;
If you just want to ignore if there is duplicate then you can use-
INSERT IGNORE INTO my_table
SELECT id,name, type
FROM other_table;
make sure that the primary key isn't the name or the type. Because you can input duplicate rows as long as you do not duplicate primary keys
I find a solution, i use a cursor:
DROP PROCEDURE proc_incremente;
DELIMITER |
CREATE PROCEDURE proc_incremente()
BEGIN
DECLARE var_name, var_type VARCHAR(100);
DECLARE var_id INT;
DECLARE end TINYINT(1) DEFAULT 0;
DECLARE cursor_incremente CURSOR
FOR SELECT * FROM other_table;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET end = 1;
OPEN cursor_incremente;
loop_cursor: LOOP
FETCH cursor_incremente INTO var_id, var_name, var_type;
IF end = 1 THEN
LEAVE loop_cursor;
END IF;
WHILE ( EXISTS( SELECT * my_table WHERE id = var_id) IS TRUE) DO
SET var_id = var_id + 1;
END WHILE;
INSERT INTO my_table(id,name,type) VALUES(var_id,var_name,var_type);
END LOOP;
CLOSE cursor_incremente;
END |
DELIMITER ;
CALL proc_incremente();

SQL trigger after update update next row

I have a table that looks something like this:
Columns:
user_id int(11) PK
module_id int(11) PK
academy_team_id int(11) PK
academy_id int(11) PK
sort_number int(11)
is_complete int(11)
score_to_pass int(11)
is_open int(11)
Now i wish to add a trigger so that when you update this table if the value is_complete is equal to 1 then update the next row's is_open and set it to1
I have attempted with the following trigger sql:
begin
if new.is_complete = 1 then
set next.is_open = 1;
end if ;
end
Sadly this did not work so im not sure how to do it can anyone push me in the right direction?
According to pala_ Answer
im getting the following error when updating my row:
ERROR 1442: 1442: Can't update table 'user_has_academy_module' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
SQL Statement:
UPDATE `system`.`user_has_academy_module` SET `is_complete`='1' WHERE `user_id`='1' and`module_id`='11' and`academy_team_id`='49' and`academy_id`='29'
Your basic trigger body should be something like this:
begin
if new.is_complete = 1 and (select id from <table> where user_id = new.user_id and module_id = new.module_id and academy_team_id = new.academy_team_id sort_number = new.sort_number +1 ) then
update <table> set is_open = 1
where user_id = new.user_id
and academy_team_id = new.academy_team_id
and module_id = new.module_id
and sort_number = new.sort_number + 1;
end if
end
It will check to see if there IS another thing to set open (based on same user_id, academy_team_id and module_id, and next sequential sort_number), and if there is, set it open.
MySQL cant update the same table the trigger is set on. It will need to be done with a stored procedure instead.
delimiter //
create procedure completeandopen(IN param INT)
begin
declare next_id integer;
declare _user_id integer;
declare _module_id integer;
declare _academy_team_id integer;
declare _sort_number integer;
select user_id,
module_id,
academy_team_id,
sort_number
into _user_id,
_module_id,
_academy_team_id,
_sort_number
from tester
where id = param;
update tester set is_complete = 1 where id = param;
select id
into next_id
from tester
where id = param + 1
and user_id = _user_id
and module_id = _module_id
and academy_team_id = _academy_team_id
and sort_number = _sort_number + 1;
if (next_id is not null) then
update tester set is_open = 1 where id = next_id;
end if;
end//
delimiter ;
I think this should work - i haven't tested on your table structure, and it does assume a unique primary key on your table. If it doesn't have that - it's easy enough to modify.
To use it, just call completeandopen(id of the row to be completed) (after changing the table name from tester to your table name)