I have two tables that look like this (of course they have a lot more rows).
AuthorID | Name | Number of albums
-------------------------------------------
1 | Santana | 39
2 | Johnny Cash | 95
AuthorID | AlbumID
----------------------
1 | 14
2 | 17
What I want to do is have a trigget that gets updated when there is a row deleted or inserted into the second table. The row I want to update in the first table is the 3rd row. Which basically represents count(AlbumID) that is also how I have calculated it. I don't really know how I would do that since until now I only created really simple triggers
It's not at all clear why you need to store a number_of_albums column in the first place. But I won't address that question. I'll answer the question you asked.
An after insert trigger on the second table can perform an update the first table, to increment the number_of_albums column for the given author_id. We'll assume the name of the first table is author and the name of the second table is album.
DELIMITER $$
CREATE TRIGGER album_ai
AFTER INSERT ON album
FOR EACH ROW
BEGIN
UPDATE author
SET number_of_albums = number_of_albums + 1
WHERE author_id = NEW.author_id;
END$$
DELIMITER ;
You could do something similar with an after delete trigger, decrementing the number_of_albums column, referencing OLD.author_id to get the value of the author_id column of the row that is deleted.
For an update, if the value of the author_id column is changed, you would need to update two rows... increment number_of_albums on one row, and decrement number_of_albums the other.
DELIMITER $$
CREATE TRIGGER album_ai
AFTER UPDATE ON album
FOR EACH ROW
BEGIN
IF NOT ( NEW.author_id <=> OLD.author_id ) THEN
UPDATE author
SET number_of_albums = number_of_albums - 1
WHERE author_id = OLD.author_id;
UPDATE author
SET number_of_albums = number_of_albums + 1
WHERE author_id = NEW.author_id;
END IF;
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 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 struggling with a trigger to update a second table based on the first table being updated.
I have tried this:
DELIMITER //
FOR EACH ROW
BEGIN
Update phpfb_picks
set points = NEW.value
where username = user and gameid = gameid
END;
//
delimiter;
but get an error about syntax.
If I do:
Update phpfb_picks
set points = NEW.value
where username = user and gameid = gameid
This works to a point. It updates all users records with the same value that was updated.
What I want to do is, when a value is updated on Table A, I want to update Table B with all records for that user, basically the 'value' from table A would always be pushed to 'points' of table B for the user, regardless if the actual record was updated.
If any record for user is updated, update all of table B records with the same value based on the username and gameid
So if Table A has the following records:
username - test
gameid - 1
value - 1
username - test
gameid - 2
value - 2
when value from row 1 is updated to 3, i want to update Table B with all the current values from table A for that user.
Is this even possible?
UPDATE:
Table A (allpoints) has columns:
username
gameid
value
TABLE B (phpfb_picks) has columns:
user
gameid
points
allpoints.username = phpfb_picks.user
allpoints.gameid = phpfb_picks.gameid
allpoints.value = phpfb_picks.points
Whenever an update is made to allpoints, I want all the records for that specific user to update all the specific records for that user in phpfb_picks, passing the allpoints.value to phpfb_picks.points based on the user and gameid
Try this trigger:
DELIMITER $$
CREATE TRIGGER update_phpfb_picks
AFTER UPDATE ON allpoints FOR EACH ROW
BEGIN
UPDATE phpfb_picks
INNER JOIN allpoints ON allpoints.username = phpfb_picks.username AND
allpoints.gameid = phpfb_picks.gameid
SET phpfb_picks.points = allpoints.value
WHERE phpfb_picks.username = NEW.username;
END;
$$
DELIMITER ;
For each row that is updated in allpoints, all rows in phpfb_picks with the same username of the updated row will be updated to the respective value of points present in allpoints as value. The trigger is an AFTER UPDATE so that the newly updated value in allpoints will also be set in phpfb_picks.
Maybe this
drop trigger if exists phpfb;
DELIMITER $$
create trigger phpfb after update on allpoints
FOR EACH ROW
BEGIN
Update phpfb_picks
set points = NEW.value
where user = new.username and gameid = new.gameid;
END $$
delimiter ;
for example
drop table if exists allpoints,phpfb_picks;
create table allpoints (username char(4),gameid int, value int);
create table phpfb_picks (user char(4),gameid int, points int);
insert into allpoints (username,gameid) values
('test',1),('test',2);
insert into phpfb_picks (user,gameid) values
('test',1),('test',1),('test',2);
update allpoints
set value = 2 where username = 'test' and gameid = 1;
result
+------+--------+--------+
| user | gameid | points |
+------+--------+--------+
| test | 1 | 2 |
| test | 1 | 2 |
| test | 2 | 0 |
+------+--------+--------+
3 rows in set (0.00 sec)
Go a quick question about triggers.
I have two tables. Namely people and attributes.
People has the following structure:
| id | firstname | surname | DOB | Age
Attributes has the following structure:
| id | person_id | haircolor | eyecolor | weight | height
And I have the following trigger:
Insert Into attributes (person_id)
SELECT id
FROM INSERTED
Which when a record gets inserted in the people table, a record gets inserted into the attributes table into the person_id column where the person_id is the same id as the person table. The rest of the inserted row is empty by default.
Now when both tables are empty and I create the first record, everything goes as expected. But when I create a second record two records get inserted into the attribute table.
I need it so that when I insert one row in the people table only one corresponding row gets inserted into the attributes table.
I am using the latest version of phpmyadmin at the time of writing.
Looking forward to hearing some responses
Cheers
You can do as following -
delimiter //
create trigger People_ins after insert on People
for each row
begin
declare pcount int;
select count(*) into pcount from attributes where person_id = new.id;
if pcount = 0 then
insert into attributes
(person_id) values (new.id);
end if;
end ;//
delimiter ;
You can skip the condition part if its always one-to-one relation.
I have a table with the following structure:
id | number | text
----------------------
1 | 1 | test
in which, id is my primary key with auto increment value. I want to make number as auto increment value too. Is it possible to have more than one auto increment column in one table?
It is not possible.There can be only one auto-increment column and it must be defined as a key in MySQL.
But You can do it by using trigger for detail go this link CREATE TRIGGER
create trigger nameTrigger before insert on tables
for each row
begin
DECLARE newNumber unsigned default 0;
SELECT Max(number)+1 INTO newNumber FROM myTable WHERE id = new.id;
UPDATE myTable SET number = newNumber WHERE id = new.id;
end