I have 2 tables:
table 1 = SAMPLE_TABLE
table 2 = RESULT_TABLE (with proposed trigger)
I would like to use a trigger in RESULT table that, when a new record is inserted into into it, will update a field in SAMPLE table called, 'status' = "complete". The field 'status' to be updated in SAMPLE is related to RESULT by:
table 1 = SAMPLE_TABLE ('client_sampleID')
=
table 2 = RESULT_TABLE ('sampleID')
This is the proposed trigger
CREATE DEFINER = `user`#`%` TRIGGER `database`.`RESULT_TABLE_BEFORE_INSERT`
AFTER INSERT ON `RESULT_TABLE` FOR EACH ROW
BEGIN
UPDATE SAMPLE_TABLE
SET status = 'complete'
WHERE SAMPLE_TABLE.client_sampleID = RESULT_TABLE.sampleID;
END
My questions:
is this above trigger OK?
there are 100+ 'client_sampleID' (all same, entered as a batch) per 'sampleID'. Is there a more efficient way of setting the 'status' so that it happens only after encountering the first instance?
You are very close. You just need to use new in the trigger:
CREATE DEFINER = `user`#`%` TRIGGER `database`.`RESULT_TABLE_BEFORE_INSERT`
AFTER INSERT ON `RESULT_TABLE` FOR EACH ROW
BEGIN
UPDATE SAMPLE_TABLE st
SET status = 'complete'
WHERE st.client_sampleID = new.sampleID;
END
Related
On a Before Insert trigger I want to calculate the value
of a column based on two colums in the inserted record
and values of columns in other tables linked to the table being updated
Testing this I just created the code to access one of the
filelds in another table up the chain. But when executing I
had an error
CREATE DEFINER = CURRENT_USER TRIGGER `infrastructure`.`Wall_Drop_BEFORE_INSERT` BEFORE INSERT ON `Wall_Drop` FOR EACH ROW
BEGIN
Declare wall_temp decimal(6,2) default null;
Declare room_temp decimal (8,2) default null;
select r.dist_wire_closet into room_temp from rooms as r
where r.Residence_residence_id = new.Wall_rooms_Residence_residence_id
and r.Residence_residence_id = new.Wall_rooms_Residence_residence_id;
END
Error message when inserting record
My mistake, 2nd line was the same as the first. I need
select r.dist_wire_closet into room_temp from rooms as r
where r.Residence_residence_id = new.Wall_rooms_Residence_residence_id
and r.room_abr = new.Wall_rooms_room_abr;
I have a MySQL database in which I have the following rows (by exemple) created by default (id, task and case may be different but the current value is always 1)
....idtaskcaseuser............datecurrent
238......31001.....0..............null..........1
239......41001.....0..............null..........1
I have to randomly create rows like this with insert statement (new rows). As you can see a date is filled and de current equal 0
....idtaskcaseuser............datecurrent
240......51001.....12015.04.03..........0
241......21002.....12015.04.03..........0
When I come across one of the lines created by default I want to use an update instead of an insert statement.
So I created the following procedure in MySQL
DELIMITER //
DROP PROCEDURE IF EXISTS FillProgress//
CREATE PROCEDURE FillProgress ( get_case INT(10),get_task INT(10), get_user INT(10) )
BEGIN
DECLARE test tinyint(1);
SET test = (SELECT COUNT(*) FROM progress WHERE case_id = get_case AND task_id = get_task);
IF test = 1 THEN
UPDATE progress SET current = 0, date = NOW(), user_id = get_user WHERE task_id = get_id AND case_id = get_case;
ELSE
INSERT INTO progress(task_id,case_id,user_id,date,current) VALUES (get_task,get_case,get_user,NOW(),0);
END IF;
END; //
DELIMITER ;
I use count to see if a already have a row with the same case and task. If it's true (test=1) I use UPDATE, otherwise and use INSERT.
If I test with the following row already wrote in the database
....idtaskcaseuserdatecurrent
241......41001.....0..null..........1
I use CALL FillProgress(1001,4,1);
The row is not updated, but I do not have any error message.
11:38:02 CALL FillProgress(1001,4,1) 0 row(s) affected 0.000 sec
And if I manually use my update query
UPDATE progress SET current = 0, date = NOW(), user_id = 1 WHERE task_id = 4 AND case_id = 1001;
It works like a charm.
The insert query also works fine.
The UPDATE query within the procedure has a "WHERE task_id = get_id" clause, however I don't see get_id being defined in the procedure; there is a "get_task" parameter for the stored procedure, though.
I have an After Insert trigger which is supposed to insert first, then do insert another table. But when any error occurs for inserting data in another table the all transaction terminated. I want to insert 1st data in base table whether the trigger fire successfully or not.
This is my code:
CREATE TRIGGER [dbo].[Insert_Teacher_Active_LC]
ON [dbo].[Teacher_Profile]
AFTER INSERT,UPDATE
AS
BEGIN
MERGE [ROSC].[dbo].[Active_LC] as d
USING (SELECT
DistrictID, upazilaID, LCID, LCVisitYr, Trimister,
CASE WHEN (TcrPres = 1 AND TcrMtchLCProf = 1)
THEN 1 ELSE 0
END AS TcrRpls
FROM INSERTED) AS s ON s.DistrictID = d.DistrictID
AND s.upazilaID = d.upazilaID
AND s.LCID = d.LCID
AND s.LCVisitYr = d.EduYr
WHEN MATCHED THEN
UPDATE
SET Trimister = s.Trimister, Tcr_Replace = s.TcrRpls
WHEN NOT MATCHED THEN
INSERT(DistrictID, UpazilaID, LCID, EduYr, Trimister, Tcr_Replace)
VALUES(DistrictID, UpazilaID, LCID, LCVisitYr, Trimister, TcrRpls);
-- Insert statements for trigger here
END
I have a TEMP table that is fed data using a Stored Proc when the table is shown through the website. This works great. I have this table as an editable one so that if/when the data in this table is edited then it will send the updated data back to my TEMP table, again this updates as it should. I now have a Trigger that will take certain fields from the TEMP and update my LIVE db table.
My problem is that when I add in other fields to update based on what is UPDATED it will do so for each row within the TEMP table. I have tried various ways, below being my last attempt to just update that particular row.
CREATE
DEFINER = 'user'#'%'
TRIGGER update_epcplanneddate
AFTER UPDATE
ON ims.temp_tobebooked
FOR EACH ROW
BEGIN
UPDATE epc_planning p
INNER JOIN temp_tobebooked b ON b.PropID = p.PropID
SET
p.EPCStatus = CASE WHEN p.PropID = b.PropID THEN 3 END,
p.EPCPlannedDate = b.EPCPlannedDate,
p.EPCBookingDate = CASE WHEN p.PropID = b.PropID THEN NOW() END,
p.LastUpdateDate = CASE WHEN p.PropID = b.PropID THEN NOW() END,
p.LastUpdateUser = b.InputBy
WHERE p.PropID = b.PropID;
END
How can I update what I need to update along with the extra fields based on this UPDATE?
So changing the JOIN to using NEW.colum the Trigger now looks like this
CREATE
DEFINER = 'user'#'%'
TRIGGER update_epcplanneddate
AFTER UPDATE
ON temp_tobebooked
FOR EACH ROW
BEGIN
UPDATE epc_planning p
SET
p.EPCStatus = 3,
p.EPCPlannedDate = NEW.EPCPlannedDate,
p.EPCBookingDate = NOW(),
p.LastUpdateDate = NOW(),
p.LastUpdateUser = NEW.InputBy
WHERE p.PropID = NEW.PropID;
END
I have a Trigger on UPDATE.
What is the correct procedure for referencing attribute from the table that is not updated by the UPDATE SQL command? Is the attribute still in the UPDATE variable? I would like to get the value of that attribute for the updated row.
You can access a values of a column before update and after update in MySQL by using keywords OLD and NEW.
For example if you want to determine whether a value of a column actually has been changed during updated you can do
IF NOT OLD.column_name <=> NEW.column_name THEN
-- do something here
END IF;
Note: <=> is NULL-safe comparison operator in MySQL
BTW: There is no UPDATED virtual table in MySQL. It's from SQL Server.
Here is a SQLFiddle demo. Note that even though update affected all records in the table, only one message has been logged in log table. It's because value for a row with id 2 in the end stayed the same.
UPDATE: to keep your finished flag in sync you need triggers for all events (insert, update, delete).
DELIMITER //
CREATE TRIGGER tg_ai_event
AFTER INSERT ON event
FOR EACH ROW
BEGIN
UPDATE activity a
SET status = (EXISTS(SELECT *
FROM event
WHERE activity = a.activity_id
AND done = 0))
WHERE activity_id = NEW.activity;
END//
CREATE TRIGGER tg_ad_event
AFTER DELETE ON event
FOR EACH ROW
BEGIN
UPDATE activity a
SET status = (EXISTS(SELECT *
FROM event
WHERE activity = a.activity_id
AND done = 0))
WHERE activity_id = OLD.activity;
END//
CREATE TRIGGER tg_au_event
AFTER UPDATE ON event
FOR EACH ROW
BEGIN
IF NOT OLD.activity <=> NEW.activity THEN
-- if activity id was changed for an event then clculate finished flag
-- for both old and new activity id
UPDATE activity a
SET status = (EXISTS(SELECT *
FROM event
WHERE activity = a.activity_id
AND done = 0))
WHERE activity_id IN(OLD.activity, NEW.activity);
ELSE
-- otherwise calculate finished flag only if done flag is changed
IF NOT OLD.done <=> NEW.done THEN
UPDATE activity a
SET status = (EXISTS(SELECT *
FROM event
WHERE activity = a.activity_id
AND done = 0))
WHERE activity_id = NEW.activity;
END IF;
END IF;
END//
DELIMITER ;
Here is SQLFiddle demo