I have two tables in mySQL, call them reviews and products. And then I have another table (call it productsmaster) that is an inner join of reviews and products. I am trying to create a trigger to run the inner join query when a new record is added to reviews.
I have tried to just insert the inner join query into the trigger, but it is returning a "#1422 - Explicit or implicit commit is not allowed in stored function or trigger." error. For clarity of the issue my code for the trigger is:
CREATE TRIGGER updateprodmaster
AFTER INSERT ON reviews
FOR EACH ROW
BEGIN
CREATE TABLE productsmaster AS
SELECT products.*, reviews.userid, reviews.usergender, reviews.userage, reviews.score
FROM products
INNER JOIN reviews
ON products.pid=reviews.pid;
END;$$
If anyone has any thoughts on this it would be much appreciated. Thanks!
Jack
The CREATE TABLE statement causes an implicit COMMIT. And that's not allowed.
There are no easy button workarounds to this limitation.
But even if you were able to workaround this limitation, why in the plastic would you want to attempt to create a new table every time a row is inserted?
When a second row is inserted, the trigger would to attempt to (again) create a table of the exact same name (which will fail because a table of that name already exists.)
Back the cart up a bit, behind the horse.
And figure out what requirement you need to meet.
When you get back to needing a trigger, you can burn that bridge when you get to it.
FOLLOWUP
If the intent is to attempt to insert a row into productsmaster table, whenever a row is inserted into the reviews table, using an after insert trigger, we'd need an INSERT statement in the trigger body.
The values of the columns of the row (that was just inserted to reviews) are available in the trigger. There's no need to select from the reviews table. We can reference the column values of the newly inserted row (in an after insert trigger) by qualifying the column names with NEW.
I recommend avoiding .*, and explicitly name the columns to be retrieved from products. I'm assuming the pid column is a unique key (or the primary key) in products.
As an example:
DELIMITER $$
CREATE TRIGGER trg_reviews_after_insert
AFTER INSERT ON reviews
FOR EACH ROW
BEGIN
INSERT INTO productsmaster (col1, col2, userid, usergender, userage, score)
SELECT p.col1
, p.col2
, NEW.userid
, NEW.usergender
, NEW.userage
, NEW.score
FROM products p
WHERE p.pid = NEW.pid;
END$$
DELIMITER $$
never use the select in triggers , triggers accept only update or insert or delete
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 running a wateranalyzer and want to save the sensor-data in a MariaDB.
I split the data into 2 tables: one for the automated part and one table which stores data I enter manually:
Tables:
I'm having a hard time (with just basic knowledge about databases) to figure out how I can "bind" ID and DateTime from one table to the other one, so if manual data is added, ID is incremented by 1 and the actual Date and Time is set in DateTime.
I bet I can do this somehow in PHPmyadmin?
thanks for your time!
using triger. this example for you.
DELIMITER //
CREATE TRIGGER contacts_after_insert
AFTER INSERT
ON contacts FOR EACH ROW
BEGIN
DECLARE vUser varchar(50);
-- Find username of person performing the INSERT into table
SELECT USER() INTO vUser;
-- Insert record into audit table
INSERT INTO contacts_audit
( contact_id,
deleted_date,
deleted_by)
VALUES
( NEW.contact_id,
SYSDATE(),
vUser );
END; //
DELIMITER ;
Is it anything more complex than having an ID in Wasser that matches the other ID? That is, first insert into Luft, then get the id and only then, INSERT INTO Wasser....
(A Trigger seems unnecessarily complicated.)
As Rick Suggested, you need to have an ID column in the second table that references ID in first table. Trigger is a better option if the process of getting the ID and inserting it along with other columns (pH, Redox...) into the second table is complicated.
Make ID in the second table as a foreign key to the ID in first table.
I'm trying to do some mysql trigger coding. I fail every time I meet loops.
CREATE TRIGGER `after_insert` AFTER INSERT ON `table_users`
FOR EACH ROW BEGIN
INSERT INTO table_user_plan (user_id, plan_id) VALUES
(NEW.id, (SELECT id FROM table_plans))
;
END
Here trigger is successfully created, but I get error
#1242 - Subquery returns more than 1 row
I understand this cannot work, because there are more than one row in table_plans... but how can I handle this if I want to add multiple rows or how can I make a loop and firstly select plans then insert into table_users?
Thanks in advanced
To insert multiple rows based on a SELECT you would use the INSERT ... SELECT FROM ... syntax. In this case, you would use something like
INSERT INTO table_user_plan
SELECT NEW.id AS user_id, tp.id AS plan_id
FROM table_plans tp;
(I think that should work, although I've never actually tried to use NEW in this context.)
I have to Write one or more triggers that keep track of how many total records have been in the sakila_film table in a single variable, but I am having trouble figuring out how to do this trigger the table is taken from http://dev.mysql.com/doc/sakila/en/sakila-structure-tables-film.html .This is what I have tried the code below but I am getting an error and I don't know any other way i could do it.
create trigger records after Update on sakila_film Count(*) from sakila_film;
Where are you planning on storing this count of total rows in the film table?
If you are going to manage this with triggers, it seems like you'd need two triggers. One for INSERT, one for DELETE. An UPDATE statement won't change the number of rows in the table. (Note that triggers are NOT fired for foreign key actions; which is a concern if there's a foreign defined with a DELETE rule.) And the triggers will not be fired for a TRUNCATE statement.
Setting aside those concerns, we'd need somewhere to store the rowcount over time. As an example:
CREATE TABLE rowcount_history_film
( ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
, rowcount INT NOT NULL
, KEY rowcount_history_film_IX1 (ts)
) Engine=MyISAM;
And then we could use trigger to insert a row into that table whenever a DML statement changes the number of rows in the film table:
DELIMITER $$
CREATE TRIGGER film_ad
AFTER DELETE ON film
FOR EACH ROW
BEGIN
INSERT INTO rowcount_history_film (ts, rowcount)
SELECT NOW(), COUNT(*) FROM film;
END$$
CREATE TRIGGER film_ai
AFTER INSERT ON film
FOR EACH ROW
BEGIN
INSERT INTO rowcount_history_film (ts, rowcount)
SELECT NOW(), COUNT(*) FROM film;
END$$
DELIMITER ;
To futher clarify i was trying to create a trigger that checks a table for a number in sql.
If it finds said number then it erases that entire row.
It uses a separate table of names to check.
I thought it be could done using a join but have had no luck.
So it would look like this I suppose if(tb1.name = tb2.name) then DELETE row.
I'm sorry if the formatting is off.
EDIT; I am using phpmyadmin so some of the the code may be missing but here is the code from my latest "attempt"
It uses on INSERT and time is set to AFTER
SELECT * FROM flights WHERE NOT EXISTS (SELECT * FROM no fly list WHERE PassengerId.Id = Passenger.Id)
have not added the DELETE as of now but the work is somewhat ongoing
Assuming that flight and dnf both have passenger_id column that uniquely identifies a passenger of interest then your trigger might look like this
DELIMITER $$
CREATE TRIGGER dnf_insert AFTER INSERT
ON dnf
FOR EACH ROW BEGIN
DELETE FROM flights WHERE passenger_id = NEW.passenger_id;
END$$
DELIMITER ;
If you post DDL (create table statements) for all relevant tables we can refine the query