Currently I'm trying to create a trigger that when the trigger fired it will update several record in same table.
After Insert TA
begin
update TA
set K = "W"
where Z = NEW.Z;
end;
But the trigger will always stop the insertion, then I found some posts and they say it is because of table being locked. When I try to unlock the table but this cannot be done in the trigger.
currently I just split the table to 1:1 relation for this problem, are there any others way you can do this?
Related
I am building a nba_players table in MySQL. It has a column for players height in inches (pl_ht_inches). It also has a column (pl_ht_feet) where it lists a players height in feet. For example nba_player Michael Jordan has pl_ht_feet = '6-6' and the pl_ht_inches is updated using the following statement:
update nba_players ab
inner join
feet_hieght_tb bc on ab.pl_ht_feet = bc.hieght
set
ab.pl_ht_inches = bc.total_inches
this statement updates nba_players.pl_ht_inches using table 'feet_hieght_tb' which has two columns
hieght - hieght varchar(4) with data like '6-6' which is imperial measurement
total_inches int(3) which lists height in inches. for example hieght '6-6' would be total_inches = 78.
I then used a trigger with the update statement. I subsequently found out that you cant reference the same table as the insert statement in the trigger for that table. The trigger reads as follows:
delimiter $$
create trigger
after_nba_players_insert
after insert on nba_players
for each row
begin
update nba_players ab
inner join feet_hieght_tb bc on ab.pl_ht_feet = bc.hieght
set ab.pl_ht_inches = bc.total_inches;
end$$
delimiter ;
this produces error 1442 when I attempt to insert new data into nba_players which means the trigger is updating the same table as as the insert into the nba_players table.
So then I tried to trigger the update by creating a stored procedure where I included the same update statement that i used for the trigger. I can call the procedure manually after doing an insert into nba_players and it works fine. But if I use the stored procedure in the trigger I get error 1442.
I dont want to have to remember to call the procedure every time I do an insert into nba_players and would like to automate this task if I could.
Is there an alternative to using triggers or stored procedure to update a column using data from a different table.
I have been researching generated columns but they dont allow select statements. What I mean by this is that the nba_players.pl_ht_inches is a foreign key to the table feet_hieght_tb that references total_inches where nba_players.pl_ht_feet = feet_hieght_tb.height. I would rather the foreign key update on its own rather than having to do this manually.
Any assistance will be greatly appreciated. Cheers.
I'm trying to create a trigger that will do two things:
Copy everything from a row in table X to a row in table Y before an UPDATE is done
Copy one column from a row in table X to a row in table Y after the UPDATE from no. 1 is done
This is what I have until now:
delimiter //
create trigger log
before update on opnaar
for each ROW
begin
set #a = opnaar.id;
set #c = opnaar.initials;
set #d = opnaar.revised;
set #f = opnaar.course;
insert into log(id,init_old,date_old,date_new,course) values (#a,#c,#d,NOW(),#f);
end;
after update on opnaar
for each ROW
begin
set #e = opnaar.initials;
insert into log(init_new) values (#e);
end;
But I figured it's not possible to add just one value to an already existing row in a table. At least, not the way I am trying to do this. Should I place the after update within the first action?
Example: I have this content:
I want to copy course, revised, initials and id to another table. That's what my first action should do.
After a teacher has updated something in that table, the NEW initials (but in the same column as the old initials) should be copied to table Y. That's what my 2nd action should do.
What am I doing wrong?
Thank you.
Have a look at the CREATE TRIGGER syntax. It is not possible to specify AFTER and BEFORE option in one trigger.
So, you should create two separate triggers.
If you want to optimize code and combine trigger's bodies, then you can write a stored proceure and call it from the triggers.
I have the following trigger:
CREATE TRIGGER sum
AFTER INSERT
ON news
FOR EACH ROW
UPDATE news SET NEW.sum = (NEW.int_views + NEW.ext_views)/NEW.pageviews
It sums the int_views and ext_views column of a table and divides them by the total pageviews.
Whenever I try to add a new row to news, I get the following error:
ERROR 1442 (HY000) at line 3: Can't update table 'news' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
The trigger seems pretty simple to me. Is there a reason why the trigger fails to run?
The symptom is, that you are running an UPDATE (for all rows) inside a INSERT trigger - both modify the table, which is not allowed.
That said, if I guess the intention of your trigger correctly, you do not want to update all rows, but only the newly inserted row. You can achieve that easily with
CREATE TRIGGER sum
BEFORE INSERT
ON news
FOR EACH ROW
SET NEW.sum = (NEW.int_views + NEW.ext_views)/NEW.pageviews
Mind that this is a BEFORE INSERT trigger, as you want to change the row before it is written to the table.
If you try to update/insert on the same table that cause trigger to fire do not use the common sql command like
-> UPDATE TABLE_NAME SET COLUMN_NAME = VALUE WHERE CONDITION_LIST;
-> INSERT INTO TABLE_NAME VALUES("VALUE1","VALUE2");
This will not work. Only use set to assign the value of the column you update.
Example:
CREATE TRIGGER trigger_name BEFORE/AFTER INSERT/UPDATE ON table_name
FOR EACH ROW
SET NEW.COLUMN_NAME = "VALUE";
I was in a similar condition where I had to run two triggers:
UPDATE 3 fields on INSERTing a new ROW
UPDATE 3 fields on UPDATEing a ROW
After lot of efforts, I was finally able to write the TRIGGER in following way:
FOR updating values on INSERT
CREATE TRIGGER `INSERT_DISCOUNT_SERVICES` BEFORE INSERT ON `services`
FOR EACH ROW SET
NEW.discount_5_rate = (NEW.ndis_rate*0.05),
NEW.discount_10_rate=(NEW.ndis_rate*0.10),
NEW.discount_15_rate=(NEW.ndis_rate*0.15)
Similarly
FOR updating values on UPDATE
CREATE TRIGGER `UPDATE_DISCOUNTS_SERVICES` BEFORE UPDATE ON `services`
FOR EACH ROW SET
NEW.discount_5_rate = (NEW.ndis_rate*0.05),
NEW.discount_10_rate=(NEW.ndis_rate*0.10),
NEW.discount_15_rate=(NEW.ndis_rate*0.15)
so i've edited my code
i had this problem in another trigger but this time even changing WHERE clause doesn't help
DELIMITER $$
CREATE TRIGGER pic_album_change AFTER UPDATE ON pictures
FOR EACH ROW BEGIN
UPDATE albums SET counter = counter + 1 WHERE albums.id = NEW.album_id;
UPDATE albums SET counter = counter - 1 WHERE albums.id = OLD.album_id;
END $$
DELIMITER ;
error :
<p>Error Number: 1442</p><p>Can't update table 'pictures' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
i dont see any changes on the pictures table in this trigger
i have another trigger that involves these two tables
DELIMITER $$
CREATE TRIGGER album_change
AFTER UPDATE
ON albums
FOR EACH ROW
BEGIN
UPDATE pictures
SET
level = NEW.level
WHERE
pictures.album_id = NEW.id ;
END $$
DELIMITER ;
Your WHERE clause is the wrong way round.
WHERE albums.id = NEW.album_id
would cause albums.counter to be incremented (presumably that's the number of pictures in each album).
It matters because joins on tables are not commutative — the direction of the join is important. Here you need to find the record in albums to update based on the value of the row in pictures.
While in this case there isn't really any ambiguity, SQL needs to follow rules about joins.
The issue with your second trigger is that MySQL is preventing a continuous cycle of updates. You have a trigger pic_album_change which updates albums when pictures is updated. And you have a trigger album_change which updates pictures when albums is updated. Those triggers will trigger each other.
It seems to me that the database design may need to be changed. Do you really need albums.counter when that data can be found with SELECT count(*) FROM pictures WHERE album_id=...? It should be possible to normalise data so that there no circular references in triggers. In fact triggers may not be necessary at all.
I am new to DB development. Please help me create a trigger for moving data from one table to another.
I have two tables, one contains "Transaction Status" from where I want to move records on transaction status change into another table having completed transactions. So the value in one table will get deleted and will get inserted into another table.
Please correct me in the following trigger:
create trigger transaction_state after update on test_archive for each row begin
insert into test_me(select * from test_archive where new.Transaction_status = 2);
delete from test_archive where new.Transaction_status = 2;
end;
Why do I feel like I am helping you with homework? Your trigger, as written, will probably move ALL rows when someone updates a row to Transaction_Status=2. Since you didn't join the NEW table to the test_archive table, your WHERE clauses will be true for all rows.
if you really want all rows with Transaction_status=2 moved from test_archive to test_me, then get rid of the FOR EACH and the references to the NEW table.
create trigger transaction_state after update on test_archive
begin
insert into test_me
select * from test_archive where Transaction_status = 2;
delete from test_archive where Transaction_status = 2;
end;