Currently I've a cron job which runs each 5 minutes and always populates: record_id, timestamp and heating status (1 and 0) in 'data' table.
I want to create a trigger which on insert to 'data' table will be capturing first occurrence of heating status '1' (heating on) and inserts data to 'heating_data' table (record_id_on, timestamp and heating_on , it needs to stay dormant until heating is set to '0' (heating off), then it should trigger update to last row and insert timestamp_off and heating_off.
DELIMITER //
create TRIGGER heating_data_insert
AFTER INSERT ON nest_stats.data
FOR EACH ROW
BEGIN
DECLARE id_exists Boolean;
select 1
into #id_exists
from nest_stats.data
where record_id= new.record_id
and heating = 1
;
if #id_exists = 1
then
insert nest_stats.heating_data
SET record_id_on= (select max(record_id) from nest_stats.data),
device_serial_number=new.device_serial_number,
user_id=new.user_id,
timestamp_on=new.timestamp,
heating_on=new.heating;
END IF;
select 2
into #id_exists
from nest_stats.data
where record_id= new.record_id
and heating = 0 ;
if #id_exists = 2
then
update nest_stats.heating_data
SET record_id_off= new.record_id,
timestamp_off=new.timestamp,
heating_off=new.heating
where record_id_on =(select max(record_id_on) from nest_stats.data);
END IF;
END;
//
DELIMITER ;
<code>
I did the following changes and worked for me.
DECLARE id_exists Boolean;
SELECT EXISTS(select record_id from nest_stats.data
where record_id= new.record_id
and heating = 1) into #id_exists;
IF #id_exists THEN
Related
I have records example:
Orden| date_record
-----|-------------------
2334 | 2017-05-17 05:00:30
2334 | 2017-05-17 05:00:50
2334 | 2017-05-17 05:10:30
3421 | 2017-05-17 07:09:40
I need to delete records that have duplicate ids only where the difference in date_record is less than 30 seconds.
Thanks
I create a table for your data Table1 and include a litle more data.
I create a temporal table newTable
include a row_number
include a field to mark for deletion
Create a function to debug you dont need it
Create a function process_time to check for deletion
Create a cursor to loop for the table and mark each row when second diff
is < 30
If a row is already marked <> 0 doesn't count for the next row calculations
The final step is delete from original table using the newTable marked rows
SQL DEMO
CREATE PROCEDURE process_time()
BEGIN
DECLARE int_id INTEGER DEFAULT 0;
DECLARE int_prev_id INTEGER DEFAULT 0;
DECLARE dtt_date datetime;
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE newTable_cursor CURSOR FOR
SELECT `ID`, `date_record`
FROM newTable
ORDER BY `ID`, `date_record`;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
OPEN newTable_cursor;
get_dates: LOOP
FETCH newTable_cursor INTO int_id, dtt_date;
IF v_finished = 1 THEN
LEAVE get_dates;
END IF;
IF int_prev_id = int_id THEN
SELECT #dd := TIMESTAMPDIFF(SECOND, MAX(`date_record`), dtt_date) as d -- MAX(`date_record`)
FROM newTable
WHERE `ID` = int_id
AND `date_record` < dtt_date
AND delete_mark = 0;
ELSE
SET int_prev_id := int_id;
SET #dd := null;
END IF;
IF #dd < 30 THEN
UPDATE newTable
SET `delete_mark` = #dd
WHERE `ID` = int_id
and `date_record` = dtt_date;
END IF;
END LOOP get_dates;
CLOSE newTable_cursor;
END;
OUTPUT
I have 3 tables : badge_master, match_result_updation and team_badges.
The badge_master is the master table where I manually insert the data acc to the excel. On match_result_updation I have some columns, if sum(goal_column1) - sum(goal_column2) = 10, then the value column1 will get the badge and it will be inserted in team_badges table. I am handling it through trigger but unable to proceed after certain time.
The trigger which I tried :
CREATE TRIGGER `afterinsert_teamgoals` AFTER INSERT ON `match_result_updation` FOR EACH ROW
BEGIN
DECLARE goalCount1 INT(10);
DECLARE goalCount2 INT(10);
DECLARE badgeId BIGINT(20);
DECLARE teamId bigint(20) default 0 ;
SELECT team1_goal INTO goalCount1 FROM match_result_updation WHERE team1_id = NEW.team1_id ;
SELECT team2_goal INTO goalCount2 FROM match_result_updation WHERE team2_id = NEW.team2_id ;
IF (goalCount1 - goalCount2 >= 10)
Then
Insert into team_badges(team_id,badge_id,match_id,timestamp)
SELECT teamId , badgeId , match_id FROM match_result_updation limit 1;
END IF;
Please Assist.
I've been trying to solve this problem. Here is the code:
CREATE TRIGGER some_trigger AFTER UPDATE ON table_a
FOR EACH ROW BEGIN
DECLARE tname VARCHAR(20);
IF (table_a.field_offer=1) THEN
SET tname='table_b';
ELSEIF (table_a.field_offer=0) THEN
SET tname='table_c';
END IF;
IF ((new.field_state = 0)) THEN
UPDATE tname join table_a on tname.ID=table_a.ref_field
SET tname.STOCK = tname.STOCK -1;
ELSEIF ((new.field_state = 1)) THEN
UPDATE tname join table_a on tname.ID=table_a.ref_field
SET tname.STOCK = tname.STOCK +1;
END IF;
END;
I am getting:
Unknown table 'table_a' in field list. Field_offer and field_state can
be null.
I've shown below what was said in the comments to the question:
CREATE TRIGGER some_trigger AFTER UPDATE ON table_a
FOR EACH ROW BEGIN
DECLARE tname VARCHAR(20);
IF (NEW.field_offer=1) THEN
UPDATE `table_b`
SET STOCK = CASE NEW.field_state
WHEN 0 THEN STOCK - 1
WHEN 1 THEN STOCK + 1
ELSE STOCK
END
WHERE ID=NEW.ref_field
;
ELSEIF (NEW.field_offer=0) THEN
UPDATE `table_c`
SET STOCK = CASE NEW.field_state
WHEN 0 THEN STOCK - 1
WHEN 1 THEN STOCK + 1
ELSE STOCK
END
WHERE ID=NEW.ref_field
;
END IF;
...
Note that I changed the updates from UPDATE ... JOIN as MySQL does not allow you to change the data of the triggered table; while you were not actually updating table_a, the JOIN could have been enough for MySQL to have objected... that and the joins would've updated every row in table_b/c that had a match in table_a, not just table_a rows related to the values in or row of the trigger.
I have a table which contains two columns
1.Clanid
2.Active
My problem is that i dont want any value in Clanid column to be inserted in this table if this value is already in Clanid column and Active for that value is 1.
For example
Clanid Active
1 1
2 1
3 0
Now it should not be possible to insert a record with Clanid=1 and Active=1 but i can insert Clanid=3 and Active=1 as this record is not there.
Try this:
delimiter //
create trigger unique_clanid
before insert on mytable
for each row
begin
if new.active and exists (
select * from mytable
where clanid = new.clanid
and active) then
signal sqlstate '02000' set MESSAGE_TEXT = 'Duplicate ClanID';
end if;
end//
delimiter ;
I think you should handle in your app level, but you want to handle in DB lavel, you can write trigger check it
you can check count record ( where Clanid = #param and Active =1)
if count > 1 : rollback
I am not available mysql to test , i just can describe my solution as following ( i;m not sure the syntax correct, it is too long time i don't write trigger in mysql)
CREATE TRIGGER test BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
DECLARE newClanId integer;
DECLARE counts integer;
Set #newClanId = NEW.Clanid;
Set #count := (SELECT count (*) FROM table_name
WHERE Clanid = #newClanId and Active =1)
IF #count > 1 THEN ROLLBACK;
END;
I created trigger on table PENDING. Pending table has 3 columns - uniqueId , duration and maxDuration. I have another table COUNT with 2 columns - req_id, total
Here is my trigger--
CREATE TRIGGER plus3second BEFORE INSERT
ON PENDING
FOR EACH ROW
BEGIN
DECLARE req_id varchar(25);
DECLARE total int(11);
DECLARE duration int(2);
SET req_id = SUBSTR(new.uniqueId, 1, 14);
Select total into total from COUNT where req_id = 'req_id';
IF total > 100 THEN
SET duration = new.duration + 3;
IF duration < new.maxDuration Then
SET new.duration = duration;
END IF;
END IF;
END
Trigger created successfully. I fired these queries on COUNT and PENDING-
insert into COUNT values ('77711422099653',200);
insert into PENDING (uniqueId, duration, maxDuration) values ('77711422099653919893277163', 3, 20);
But trigger not working ...Where is the problem ?
Check with this trigger definition(with less conflicting names):
CREATE TRIGGER plus3second
BEFORE INSERT
ON PENDING
FOR EACH ROW
BEGIN
DECLARE tReqID varchar(25);
DECLARE tTotal int(11);
DECLARE tDuration int(2);
SET tReqID = SUBSTR(new.uniqueId, 1, 14);
SELECT total
INTO tTotal
FROM COUNT
WHERE req_id = tReqID;
IF tTotal > 100
THEN
SET tDuration = new.duration + 3;
IF tDuration < new.maxDuration
THEN
SET new.duration = tDuration;
END IF;
END IF;
END