I want to write a trigger in MySQL which copy table1’s column1 to table2’s column1
But table2’s column1 must to be unique, table1’s column1 is duplicable.
Any one suggest me how to conditionally sync up between this 2 tables using triggers.
You could improve your question by stating what kind of trigger you want (insert,update,delete) and what you want to happen if a duplicate is found. Assuming you want an insert trigger and table2.id has unique key you could use insert ignore to ignore the error and throw away the the attempted insert from table1 , you could use insert..on duplicate key to update table2. If table2.id does not have a unique key you could code to find if the key would be duplicated and then apply the insert option you prefer. I have assumed that you don't simply want to throw an error if a duplicate is encountered. Here's some sample code and data for you.
DROP TABLE IF EXISTS TABLE1,TABLE2;
CREATE TABLE TABLE1(ID INT, VALUE INT);
CREATE TABLE TABLE2(ID INT PRIMARY KEY, VALUE INT);
DROP TRIGGER IF EXISTS T;
DELIMITER $$
CREATE TRIGGER T AFTER INSERT ON TABLE1
FOR EACH ROW
BEGIN
INSERT IGNORE INTO TABLE2 VALUES (NEW.ID,NEW.VALUE);
END $$
INSERT INTO TABLE1 VALUES(1,1);
SELECT * FROM TABLE2;
INSERT INTO TABLE1 VALUES(1,2);
SELECT * FROM TABLE1;
SELECT * FROM TABLE2;
DROP TRIGGER IF EXISTS T;
DELIMITER $$
CREATE TRIGGER T AFTER INSERT ON TABLE1
FOR EACH ROW
BEGIN
INSERT INTO TABLE2 VALUES (NEW.ID,NEW.VALUE)
ON DUPLICATE KEY UPDATE VALUE = NEW.VALUE;
END $$
DELIMITER ;
SELECT * FROM TABLE2;
INSERT INTO TABLE1 VALUES(1,3);
SELECT * FROM TABLE1;
SELECT * FROM TABLE2;
DROP TRIGGER IF EXISTS T;
DELIMITER $$
CREATE TRIGGER T AFTER INSERT ON TABLE1
FOR EACH ROW
BEGIN
DECLARE FOUND INT DEFAULT 0;
SELECT 1 INTO FOUND FROM DUAL WHERE EXISTS(SELECT ID FROM TABLE2 WHERE ID = NEW.ID);
IF FOUND = 0 THEN
INSERT INTO TABLE2 VALUES (NEW.ID,NEW.VALUE);
ELSE
INSERT INTO TABLE2 VALUES (NEW.ID,NEW.VALUE)
ON DUPLICATE KEY UPDATE VALUE = NEW.VALUE;
END IF;
END $$
DELIMITER ;
SELECT * FROM TABLE2;
INSERT INTO TABLE1 VALUES(1,4),(2,1);
SELECT * FROM TABLE1;
SELECT * FROM TABLE2;
Related
I have a trigger which copies the inserted data from my table 1 to table 2. I tried inserting 2 data into table 1 and it copies it to my table 2 but the the problem is it copies 2 times the data. Whenever I insert A, B, C into table 1 the value being copied in my table 2 is A, A, A, B, B, B, C, C, C. Please help.
delimiter //
CREATE TRIGGER `copy_table` AFTER INSERT ON table_2
insert into table_1 (id, code, name)
select id, code, name
from table_2;
END;
//
delimiter ;
Your problem is that you are inserting all the data from table_2 into table_1 each time your trigger executes. You need to only insert the new values, which you can do by referring to the NEW pseudo-table:
delimiter //
CREATE TRIGGER `copy_table` AFTER INSERT ON table_2
FOR EACH ROW
BEGIN
INSERT INTO table_1 (id, code, name)
VALUES (NEW.id, NEW.code, NEW.name);
END;
//
delimiter ;
Demo on dbfiddle
Update
If you want the trigger to only insert values if they don't already exist in table_1, you can either
add a UNIQUE index on (id, code, name) to table_1 and use INSERT IGNORE in the trigger; or
Update the trigger to check that the data doesn't exist in the table already:
CREATE TRIGGER `copy_table` AFTER INSERT ON table_2
FOR EACH ROW
BEGIN
IF NOT EXISTS (SELECT *
FROM table_1
WHERE id = NEW.id AND code = NEW.code AND name = NEW.name) THEN
INSERT INTO table_1 (id, code, name) VALUES (NEW.id, NEW.code, NEW.name);
END IF;
END;
Demo on dbfiddle
I have table1 & table2 (with foreign key) see tables :
I want query that can put same value automatically as
(INSERT INTO table2 (table2.foreignKey) VALUES (table1.id))
You can use a Trigger to do this.
It would look somewhat like this:
delimiter |
CREATE TRIGGER insertIntoTable2 AFTER INSERT ON table1
FOR EACH ROW
BEGIN
INSERT INTO table2 SET foreignKey = NEW.id;
END;
|
delimiter ;
I'm pretty new to this whole trigger thing with PHPMyAdmin. I don't really know what I am doing wrong but I want simply to copy all the data from table1 to table2 like an archive or something like that. Everytime there is an insert it should copy the data to table2.
Table1 has these attributes/fields:
ID
customerID
BookSN(SN = serialnumber)
created_at(when he lend the book)
updated_at(when he gave the book back)
Table2:
Has the same attributes/fields as Table1
I'm trying to solve this:
delimiter //
CREATE TRIGGER `simple_copy` AFTER INSERT ON table1
FOR EACH ROW BEGIN
insert into table2(id, customerID, BookSN, created_at,updated_at)
select ?? -- i dont know what to write here...
from table1;
END;
//
delimiter ;
I would be really grateful if you can help me to fix this total mess.
If there are some data in table1 that you would want to copy in table2 then first run this:
INSERT INTO table2(id, customerID, BookSN, created_at, updated_at)
SELECT id, customerID, BookSN, created_at, updated_at
FROM table1;
Then you can now use a trigger to continuously copy the newly inserted data from table1 into table2.
DELIMITER //
CREATE TRIGGER `simple_copy` AFTER INSERT ON table1
FOR EACH ROW BEGIN
INSERT INTO table2(id, customerID, BookSN, created_at, updated_at)
VALUE (new.id, new.customerID, new.BookSN, new.created_at, new.updated_at);
END//
DELIMITER ;
But if table1 is empty then just go at once with the trigger.
If you want to copy all columns you have to use like this
delimiter #
CREATE TRIGGER `simple_copy` AFTER INSERT ON table1
FOR EACH ROW
BEGIN
insert into table2(id, customerID, BookSN, created_at,updated_at)
values (new.id, new.customerID, new.BookSN, new.created_at,new.updated_at)
from table1;
END#
delimiter ;
I have two tables:table1 and rating
table1(id,name,category)
rating (cid,rating,total_rating,total_rates,photoID)
and now when i insert data into table1 i want to set all data in table rating at zero for that specific photoID from table1, but i dont know how..can someone help me?
You can use LAST_INSERT_ID() to retrieve the ID you just inserted. For example, assuming PhotoID is the relation between table1 and rating:
insert table1 (name,category) values ('waterfall 2', 'nature');
insert rating (rating,total_rating,total_rates,photoID) values
(0, 0, 0, last_insert_id());
I'd rather create a STORED PROCEDURE to make a single call from application. Assuming that you want to INSERT a record on table rating for every insert on table1 and that ID on table1 is set as AUTO_INCREMENT.
DELIMITER $$
CREATE PROCEDURE procedureName
(
IN _name VARCHAR(25),
IN _category VARCHAR(25)
)
BEGIN
INSERT INTO table1 (name, category)
VALUES (_name, _category);
SET #last_ID := LAST_INSERT_ID();
INSERT INTO rating (cid, rating, total_rating, total_rates, photoID)
VALUES (#last_ID, 0,0,0,0);
END $$
DELIMITER ;
and call the procedure,
CALL procedureName('nameHere','categoryHere')
You can use MySql triggers http://dev.mysql.com/doc/refman/5.0/en/trigger-syntax.html:
CREATE TRIGGER ins_rating AFTER INSERT ON table1
FOR EACH ROW
BEGIN
INSERT INTO rating (cid,rating,total_rating,total_rates,photoID)
VALUES( NEW.ID ,0,0,0,null)
END;
If you want to insert data into TABLE1 and delete it from TABLE2, you can write below listed query:
mysql_query("DELETE * FROM table2");
I have these two tables:
create table possiede (
soc1 integer not null,
soc2 integer not null,
primary key (soc1,soc2),
perc double
);
create table contr (
soc1 integer not null,
soc2 integer not null,
primary key(soc1, soc2)
);
I have these two triggers in a generic SQL syntax and I need to translate them into MySQL syntax:
create trigger contrDir
after insert on possiede
for each row
when percent > 0.5 and (soc1,soc2) not in (select * from contr)
insert into contr values (soc1,soc2);
create trigger contrIndir
after insert on possiede
referencing new table as newTable
for each row
insert into possiede values
(select P.soc1, N.soc2, P.perc+N.perc
from newTable as N join possiede as P on N.soc1 = P.soc2);
this was my first try, but it gives me an error on "referencing" keyword ("syntax error, unexpected IDENT_QUOTED, expecting FOR_SYM") and I'm not sure the translation is correct:
create trigger controllo
after insert on possiede
REFERENCING new table as newTable
for each row
begin
insert into possiede (select P.soc1, N.soc2, P.perc+N.perc from
newTable as N join possiede as P on N.soc1=P.soc2);
if percent > 0.5 and (soc1,soc2) not in (select * from contr) then
insert into contr values (soc1,soc2);
end if;
end;
also as you noticed I had to compress two triggers into one because of some MySQL constraints. Could somebody give me the right translation?
Please put the column names inside the braces and use NEW_TABLE. In addition, I think the IN CLAUSE within IF BLOCK is incorrect as you are checking two columns(soc1 and soc2) against select * from.... Please try using the updated query as below:
CREATE TRIGGER controllo
AFTER INSERT on possiede
REFERENCING NEW_TABLE AS newTable
FOR EACH ROW
BEGIN
INSERT INTO possiede (soc1, soc2, perc)
SELECT P.soc1, N.soc2, P.perc+N.perc
FROM newTable AS N JOIN possiede AS P ON N.soc1=P.soc2;
IF percent > 0.5 and soc1 not in (select soc1 from contr)
and soc2 not in (select soc2 from contr)
THEN
INSERT INTO contr VALUES (soc1,soc2);
END IF;
END;