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;
Related
Please I did this trigger to update table rating after each insert when 2 columns (id_prof,id_etud) inserted are already in the table but it gives mi this error
> #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 6
The trigger :
CREATE TRIGGER Before_Insert_Rate
BEFORE INSERT ON rating
FOR EACH ROW
BEGIN
IF (EXISTS(SELECT * FROM rating WHERE id_prof=NEW.id_prof and id_etud = NEW.id_etud)) THEN
UPDATE `rating` SET `rate` = NEW.rate WHERE `id_prof` = NEW.id_prof and `id_etud` = NEW.id_etud;
ELSE INSERT INTO rating VALUES (NEW.idprof,New.rate,New.id_etud);
END IF
END
DELIMITER ;
You must set the DELIMITER before. Change it to:
DELIMITER //
CREATE TRIGGER Before_Insert_Rate
BEFORE INSERT ON rating
FOR EACH ROW
BEGIN
IF (EXISTS(SELECT * FROM rating WHERE id_prof=NEW.id_prof and id_etud = NEW.id_etud)) THEN
UPDATE `rating` SET `rate` = NEW.rate WHERE `id_prof` = NEW.id_prof and `id_etud` = NEW.id_etud;
ELSE INSERT INTO rating VALUES (NEW.idprof,New.rate,New.id_etud);
END IF
END; //
DELIMITER ;
from the official reference manual.
A trigger can access both old and new data in its own table. A trigger
can also affect other tables, but it is not permitted to modify a
table that is already being used (for reading or writing) by the
statement that invoked the function or trigger.
This means no query on table X can INSERT, UPDATE, or DELETE from table X; it also means that if a trigger on table X modifies table Y, it will fail for any query using both table X and Y that "triggers" it.
Example: UPDATE x INNER JOIN y ON x.id = y.id SET x.something = 1, y.something = 2 will cause a BEFORE UPDATE ON x trigger (that updates, inserts, or deletes from y) to fail.
I solved it using ON DUPLICATE KEY on a query instead of trigger
CREATE TABLE `rating` (
`id_prof` int(11) NOT NULL,
`rate` float NOT NULL,
`id_etud` int(11) NOT NULL,
UNIQUE (id_prof,id_etud)
)
the query :
INSERT INTO rating (id_prof,rate,id_etud) VALUES (1,2,5)
ON DUPLICATE KEY UPDATE rate=2
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
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.
In the code below I'm trying to create a trigger which inserts 'incidentimg' table id along with an image path if the user of the web application did not upload a image with the form belonging to 'incidentreport' table, however, I'm only getting the error "MySQL said: #1422 - Explicit or implicit commit is not allowed in stored function or trigger"
DROP TRIGGER IF EXISTS `insertImage`;
CREATE TRIGGER `insertImage` AFTER INSERT ON `incidentreport`
FOR EACH ROW
BEGIN
IF(SELECT incidentimg.incidentImgId FROM incidentimg
LEFT JOIN incidentreport ON incidentimg.imgs_incidentReportId = incidentreport.incidentReportId
WHERE incidentimg.incidentImgId IS NULL)
THEN INSERT INTO incidentimg(incidentImgId, imgUrl)values(NEW.incidentReportId, 'images/no-image.png');
END IF;
END
;
Here are the tables being used
Can someone assist me on how to correct this problem
I finally got the code to work. Now the code will check whether 'incidentimg' table has all the 'incidentReportId' that the 'incidentreport' table has, and if it doesn't then the last inserted id from the 'incidentreport' table along with a default image path will be inserted into 'incidentimg' table AFTER INSERT.
CREATE TRIGGER insertImage AFTER INSERT ON incidentreport
FOR EACH ROW
BEGIN
IF(SELECT incidentreport.incidentReportId
FROM incidentreport
LEFT JOIN incidentimg ON incidentreport.incidentReportId = incidentimg.imgs_incidentReportId
WHERE incidentimg.imgs_incidentReportId IS NULL)
THEN INSERT INTO incidentimg(imgs_incidentReportId, imgUrl) VALUES(NEW.incidentReportId, 'images/no-image.png');
END IF;
END
I am not much sure but I am guessing that probably it's because of the IF .. THEN conditional INSERT. Try modifying your INSERT statement with an EXISTS like
DROP TRIGGER IF EXISTS `insertImage`;
CREATE TRIGGER `insertImage` AFTER INSERT ON `incidentreport`
FOR EACH ROW
BEGIN
INSERT INTO incidentimg(incidentImgId, imgUrl)
SELECT NEW.incidentReportId, 'images/no-image.png'
FROM DUAL WHERE EXISTS (
SELECT 1 FROM incidentimg
LEFT JOIN incidentreport
ON incidentimg.imgs_incidentReportId = incidentreport.incidentReportId
WHERE incidentimg.incidentImgId IS NULL
)
END;
I want to generate PK through trigger as it is custom PK.
It is like depending on the member type field, I want to generate member id which is PK.
e.g. if new record's member type is DGIA, then member id will be DGIA1, DGIA2, DGIA3 ...and so on... if member type is DGIL, then member id will be DGIL1, DGIL2, DGIL3 ...and so on...
So, how to write trigger for the same... I have tried as following but it is working for 1st record only.
ALTER TRIGGER [dbo].[next_member_id] ON [dbo].[DAD_MEMBERSHIP] AFTER INSERT
AS
BEGIN
DECLARE #COUNT INT
SET #COUNT=0;
SELECT #COUNT=ISNULL(MAX(CAST(SUBSTRING(DAD_MEMBERSHIP.MEMBER_ID,5,15) AS INT)),0)+1 FROM DAD_MEMBERSHIP where DAD_MEMBERSHIP.MEMBER_TYPE = DAD_MEMBERSHIP.MEMBER_TYPE
update DAD_MEMBERSHIP set DAD_MEMBERSHIP.MEMBER_ID = DAD_MEMBERSHIP.MEMBER_TYPE + CONVERT(varchar,#COUNT)
from DAD_MEMBERSHIP inner join inserted on DAD_MEMBERSHIP.MEMBER_TYPE = inserted.MEMBER_TYPE
END
Triggers operate by batch of records, you cannot assign to a scalar variable and expect it to work for more than one record. You need to rethink your whole process into a set-based process.
I solved the problem using following trigger
ALTER TRIGGER [dbo].[next_member_id]
ON [dbo].[DAD_MEMBERSHIP]
AFTER INSERT
AS
BEGIN
DECLARE #COUNT INT
SET #COUNT=0;
DECLARE #STR VARCHAR(5)
SET #STR=''
select #STR=i.MEMBER_TYPE from inserted i;
SELECT #COUNT=ISNULL(MAX(CAST(SUBSTRING(DAD_MEMBERSHIP.MEMBER_ID,5,15) AS INT)),0)+1
from DAD_MEMBERSHIP where MEMBER_TYPE=#STR
update DAD_MEMBERSHIP set DAD_MEMBERSHIP.MEMBER_ID = #STR + CONVERT(varchar,#COUNT)
from DAD_MEMBERSHIP inner join inserted i on i.MEMBER_TYPE=DAD_MEMBERSHIP.MEMBER_TYPE where DAD_MEMBERSHIP.MEMBER_ID is null
END