I need to create a trigger (after insert on one table) on MySQL, but the action needs to join 2 tables, for inserting into a third table. My script below returns no error, but the row is not inserted into the third table.
The first table (on which the after-insert trigger should work):
Z_TAXO
ID term_ID taxo_name
1 1 dept
2 2 staff
3 4 course
4 5 dept
The second table to be joined in the trigger:
Z_TERM
term_ID name
1 Engineering
2 Andy
4 Metallurgy
5 Business
6 Arts
The third table. If the Z_TAXO table has a new row with taxo_name = "dept", the row (joined with table Z_TERM) needs to be inserted into this table:
Z_DEPTS
ID dept_name
1 Engineering
4 Business
I created a trigger:
delimiter //
CREATE TRIGGER TRG_NEW_DEPT
AFTER INSERT ON Z_TAXO
FOR EACH ROW
BEGIN
DECLARE _dept_ID bigint(20);
DECLARE _dept_name varchar(200);
IF Z_TAXO.taxo_name = "DEPT" THEN
BEGIN
SELECT Z_TAXO.ID INTO _dept_ID FROM Z_TAXO, Z_TERM
WHERE Z_TAXO.ID = new.Z_TAXO.ID AND Z_TAXO.term_ID = Z_TERM.term_ID;
SELECT Z_TERM.name INTO _dept_name FROM Z_TERM, Z_TAXO
WHERE Z_TAXO.term_ID = Z_TERM.term_ID AND Z_TAXO.ID = new.Z_TAXO.ID;
INSERT INTO Z_DEPTS (ID, dept_name) VALUES (_dept_ID, _dept_name);
END;
END IF;
END//
delimiter ;
Then inserted a row to the Z_TAXO table:
INSERT INTO Z_TAXO (ID, term_ID, taxo_name) VALUES (5, 6, "dept");
Expecting to have this new row in table Z_DEPTS:
ID dept_name
5 Arts
But when I select * from Z_DEPTS, the result is still:
ID dept_name
1 Engineering
4 Business
What can be wrong? I can't modify the design of the tables, because they came from a wordpress Plugin. Thanks in advance!
Couple of comments about your code. 1) When using new. qualifiers you don't further qualify with the table name so new.z_taxo.id is invalid andd should simply be new.id 2) You don't need a begin..end block in a mysql if statement 3) if just doesn't make sense referring to the table z_taxo in your select stataments - a simple insert select will do.
try
drop trigger if exists trg_new_dept;
delimiter //
CREATE TRIGGER TRG_NEW_DEPT
AFTER INSERT ON Z_TAXO
FOR EACH ROW
BEGIN
INSERT INTO Z_DEPTS (ID, dept_name)
select term_id, name
from z_term
where term_id = new.term_id;
END//
delimiter ;
Related
I have two tables I'm working with: Records and Invoice. Invoice contains a column for the primary key of Records to be stored as a foreign key.
I'm looking to create a trigger. Immediately when a new row is generated in Records, I want a new row to also be created in Invoice, and I want the PK from Records to be inserted into the corresponding column in invoice.
For example, let's say the tables are Records(RecordsID) and invoice(invoiceID, RecordsID)
When new row created in tbl Records
Create new row in tbl Invoice and insert new Records.RecordID into new invoice.invoiceID
I'm aware this is most likely very far off, but here is the trigger I've been working on:
DELIMITER $$
create trigger new_invoice
after insert
on main for each row
begin
if new.RecordID is not null then
insert into invoice(RecordID)
values(new.RecordID(new.RecordID));
END IF;
END$$
DELIMITER ;
Any assistance will be greatly appreciated.
Thank you.
Yes you have it almost right
CREATE tABLE main(RecordID int)
CREATE tABLE invoice (RecordID int)
create trigger new_invoice
after insert
on main for each row
begin
if new.RecordID is not null then
insert into invoice(RecordID)
values(new.RecordID);
END IF;
END
INSERT INTO main VALUES (1)
SELECT * FROM invoice
| RecordID |
| -------: |
| 1 |
db<>fiddle here
I am trying to create a trigger in mysql that updates Table B with values from Table C, after a new record is inserted into Table A. I've tried a few variations of the code below, but can't get it to work. Can anyone point me in the right direction?
delimiter //
CREATE TRIGGER updateC AFTER Insert ON Table A
FOR EACH ROW in TableB
BEGIN
IF TableB.Group = 1 THEN
Insert into TableC(inserthere) values (TableB.AddThis);
END IF;
END;//
delimiter ;
Table A includes the fields ProjectID | TaskGroup.
Table B includes the fields ID | DefaultTask | TaskGroup.
Table C includes the fields ID | ProjectID | DefaultTask.
When a new ProjectID & TaskGroup are added to table A, I would like to find all DefaultTasks in TableB that have the same TaskGroup, and then insert those DefaultTasks & the ProjectID as new records in Table C
After You e explanation in the comment.
This shows you how to do it, you Must test The INSERT Query, it assumes that id is an autoincrement.
Every NEW.columname is the value of the inserted row.
With INSERT INTO ... SELCT You can male a bulk insert from all Values from Taböleb that fit the bill
DELIMITER //
CREATE TRIGGER updateC AFTER Insert ON TableA
FOR EACH ROW
BEGIN
INSERT INTO TableC (ProjectID,DefaultTask) SELECT NEW.ProjectID,DefaultTask
FROM TABLEB
WHERE TaskGroup = NEW.TaskGroup;
END;//
DELIMITER ;
FYI: Write sql Comands in UPPER case, it smales the reading much more simple
Can anyone point me in the right direction?
The record inserted into A must define the record(s) in B which must be updated, and the records in C which values must be taken for this update.
For example, it may be
CREATE TRIGGER updateC
AFTER INSERT
ON Table A
FOR EACH ROW
UPDATE B, C
SET B.field1 = C.field2
WHERE B.field3 = NEW.field4
AND C.field5 = NEW.field6;
I have these two table called "cases" and attendance respectively which has four columns:
cases-
id empid reaction date_t
1 EMP12654 interested 2017-09-22
attendance-
id empid logintime logouttime date_t flag workinghours call_att
1 EMP12654 00:14:49 05:14:49 2017-09-18 set 6 1
What I want to do is create a trigger on cases table that updates call_att column of attendance table with number of entries in reaction column of cases table, this is what I have tried so far
CREATE DEFINER=`root`#`localhost` TRIGGER `number_call`
AFTER INSERT ON `cases` FOR EACH ROW
BEGIN UPDATE attendance set call_att=call_att +1
WHERE empid=new.empid AND date_t=new.date_t; END
But that doesn't seem to work. I am quite new to triggers.
try this
CREATE TRIGGER number_call
AFTER INSERT ON cases
FOR EACH ROW
BEGIN
UPDATE attendance set call_att=(select count(*) from cases where empid=NEW.empid )
date_t=NEW.date_t;
END
I am adding new user to database user_data. My trigger has to store id of semester (from insert query) on high school and then select from another database list of subjects, which are taught this semester.
At the end it has to insert into grades table rows which constains id of user, id of semester, and id of subject. I want to add that there are multiple subjects in semester.
Here is a sample trigger:
CREATE DEFINER=`root`#`localhost` TRIGGER `data_shipment_extras_BEFORE_INSERT` BEFORE INSERT ON `users` FOR EACH ROW
BEGIN
DECLARE semester_id DATETIME;
SELECT
semester_id
INTO #semester_id
FROM other_database.subjects s
WHERE s.user_id = NEW.id;
SET NEW.semester_id = #semester_id;
END
Simply modify it a bit for your needs.
I have 3 tables
old_customers
id name
5 Mario
13 John
.. ...
new_customers
id name address
7 Luigi Roma
.. ... ...
orders
id customer_id
1 5
2 7
3 13
.. ..
I want to copy old_customers to new_customers assigning them a new auto-increment id and updating the orders foreign key customer_id.
How to perform this simultaneous INSERT and UPDATE in one simple MySQL query?
A basic psudo-sql idea
INSERT INTO new_customers (name) SELECT name FROM old_customers
AND
UPDATE orders SET customer_id=LAST_INSERT_ID() WHERE customer_id=old_customers.id
A week later ...
Thanks to help received this is the developed MySQL solution:
create a PROCEDURE that declare a CURSOR and INSERT+UPDATE fetched results in a LOOP
DELIMITER //
CREATE PROCEDURE move_costumers()
BEGIN
DECLARE fetched_id INT(3);
DECLARE fetched_name VARCHAR(50);
DECLARE my_cursor CURSOR FOR SELECT id,name FROM old_customers;
OPEN my_cursor;
BEGIN
DECLARE EXIT HANDLER FOR NOT FOUND BEGIN END;
LOOP
FETCH my_cursor INTO fetched_id,fetched_name;
INSERT INTO new_customers (name) VALUES (fetched_name);
UPDATE orders SET orders.customer_id = LAST_INSERT_ID()
WHERE orders.customer_id = fetched_id;
END LOOP;
END;
CLOSE my_cursor;
END//
It's a loop without control variable and without label, as I found in Simple Cursor Traversal 2
Why dont you write a udf, it will help you achieve your requirement.
The procedure for this purpose will be something like this ::
Follow the steps ::
1)Get the largest id used in new_customer table eg.
(Select max(id) into v_curr_id from new_users group by user_id)
and store it in a variable as v_curr_id.
2) Create a cursor which iterates and reads every row of the old_customer and everytime store it into a variable v_old_cust_id, v_old_custname
3)Inside the cursor :
increment the v_curr_id and insert a new row in the new_cust table having the cust_id as v_curr_id and name as v_old_custname.
e.g.
insert into new_customers(id, name) values (v_curr_id,v_old_custname);
Then update the order_table like
update order_table set cust_id = v_curr_id where cust_id=v_old_custname;
4) After creation you will just have to call the procedure
like
call my_proc()
For syntax reference, visit cursor_example
UDF? come on...
just copy old customer data into new_customer table, adding old_id as a column so you could update this way:
INSERT INTO new_customers (name,old_id) SELECT name, id FROM old_customers
UPDATE orders o
SET customer_id = (select id form new_customers nc where nc.old_id = o.id)
Proc with cursor will be soooo slow...