I create a trigger in MySQL to delete all rows that depend on that OLD row.
Some menu items can be a sub-menu item, so the field menu_in has the parent item menu_id.
CREATE TRIGGER DEL_MENU_DEPENDENCIES
BEFORE DELETE ON menu
FOR EACH ROW BEGIN
DELETE FROM menu WHERE menu_in = OLD.menu_id;
END
But I get an error:
General error: 1442 Can't update table 'menu' in stored function/trigger because it is already used by statement which invoked this stored function/trigger
I already try "AFTER" but is the same problem.
This are the fields in table:
menu_id | menu_in | name
I search in Google but I did not find a solution.
It seems that it has to do with the possibility of creating an infinite loop.
But apparently the loop would stop if there are no more rows. Right?
Thank you in advance for all your attention.
EDIT
+---------+---------+------+
| menu_id | menu_in | name |
+---------+---------+------+
| 1 | 0 | mn1 |
+---------+---------+------+
| 2 | 0 | mn2 |
+---------+---------+------+
| 3 | 1 | mn3 |
+---------+---------+------+
| 4 | 1 | mn4 |
+---------+---------+------+
| 5 | 4 | mn5 |
+---------+---------+------+
| 6 | 2 | mn6 |
+---------+---------+------+
| 7 | 5 | mn7 |
+---------+---------+------+
Imagine that I need to delete row menu_id = 1. It would delete lines 3, 4, 5 and 7. Because they create a chain.
With a trigger in MySQL it would be great to do this. I would need just to delete one row, trigger would do the rest.
Thank you.
You can't do this with a trigger in MySQL or MariaDB.
https://dev.mysql.com/doc/refman/en/stored-program-restrictions.html says:
A stored function or trigger cannot modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
You could accomplish what you describe by using a foreign key with the ON DELETE CASCADE option. Read https://dev.mysql.com/doc/refman/en/create-table-foreign-keys.html#foreign-key-referential-actions for details.
Related
hey guys I'm having trouble creating a trigger statement for my tables. I'm using the gui interface provided in phpmyadmin to create the statement, but whenever I run the insert command on the list_item table it throws the error #1054 - Unknown column 'list_item.list_item_id' in 'where clause'. I'm not sure what I've done wrong here, i do notice in the gui interface in the where clause list_item doesn't get highlighted like the other table names do. any tips on how I can fix this would be greatly appreciated!!
also i feel like i should mention what im trying to accomplish is when i add an item to the list_item table the count column in the list table should be incremented by 1 based on the list_item_id of the inserted item.
list_item table:
| id | list_item_id |
| -- | ------------ |
| 1 | 1 |
| 2 | 2 |
| 3 | 1 |
list table:
| id | list_id | count |
| -- | --------| ----- |
| 1 | 1 | 2 |
| 2 | 2 | 1 |
CREATE TRIGGER `insert_update`
AFTER INSERT ON `list_item`
FOR EACH ROW
UPDATE list
SET list.count = list.count + 1
WHERE list.list_id = list_item.list_item_id
The error is thrown because you don't invoke list_item in the update statement. However if you did another error would be thrown and would be logically incorrect, you should be testing against NEW. values
WHERE list.list_id = NEW.list_item_id
Review the manual for more details https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html
Please Help me to create triggers,
I have 2 tables of
data
+---------+------------+-------+-------+
| id | info_id | rate | qty | total |
+----+---------+------------+----------+
| 80 | 10 | 150 | 5 | 750 |
+----+---------+-------+-------+-------+
| 81 | 10 | 50 | 5 | 250 |
+--------------+-------+-------+-------+
info
+---------+---------------+------------+
| id | name | gtotal | dated |
+-----+--------+----------+------------+
| 10 | Hari | NULL | 2021-05-15 |
+---------+------------+---------------+
I want to create a trigger through phpmyadmin, as soon as data will be inserted, then info.gtotal will be updated by adding data.total from matched info_id from table name- data.
what will be the trigger if update on data happens too. I just want to create both triggers.
I am new with such, please help me. Any help is accepted.
You need to create two triggers one for insert and another for update.
CREATE TRIGGER `insert_trigger`
AFTER INSERT ON `data`
FOR EACH ROW
UPDATE info
SET gtotal = gtotal + new.total
WHERE id = new.info_id;
Here new.info_id will have the info_id value of newly insert record
CREATE TRIGGER `update_trigger`
AFTER UPDATE ON `data`
FOR EACH ROW
UPDATE info
SET gtotal = (gtotal - old.total) + new.total
WHERE id = new.info_id;
Here old.total will have the total value of record before updating. new.total is the total value after updation.
Since you haven't conveyed what to do after update I have added the logic of subtracting the total from old total and added the new total value. Change it as per your requirement.
You can also create these triggers using GUI in phpmyadmin. You have to select the triggers in the menu bar and add the trigger definition.
Consider the table TRADE_ORDERS.
Symbol | Type | Count | Settled | Settled_count
------ | -----| ------| --------| -------------
Apple | BUY | 100 | NO | 0
Apple | BUY | 50 | NO | 0
I have written a trigger after_trade_orders_insert that will AFTER INSERT of a new row will try to settle the previous orders depending on the if there are unsettled orders.
Now if I INSERT into TRADE_ORDERS the row with values Apple, SELL, 150, it should settle all the bought shares. So the intended action should bring the table to below state.
Intended Output
Symbol | Type | Count | Settled | Settled_count
------ | -----| ------| --------| -------------
Apple | BUY | 100 | YES | 100
Apple | BUY | 50 | YES | 50
Apple | SELL | 150 | YES | 150
I understand how to write code in mysql to achieve. But when I write the code to do that in after_trade_orders_insert, it fails with error
Error Code: 1442. Can't update table 'NSE_FO' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. 0.055 sec
I understand what this error is and why it happens.
Question: How do I achieve the intended output?
you can not update recently inserted row in table by trigger so , you have to use where clause with new keyword.
We cannot do what we want to do - A Trigger/Stored procedure cannot update another row of the same table as the row, the trigger was called from.
How to achieve it?
From an accepted answer on this thread
The typical way to do that, is to create a stored procedure, that
inserts into/Updates the target table, then updates the other row(s),
all in a transaction.
I've come across this problem numerous times but haven't found a "MySQL way" to solve the issue as such - I have a database that contains users and reports. Each report has an id which I display as a report number to my users.
The main complaint is that users are confused as to why reports have gone missing from their system. This is not actually the case. It is actually that they are recognizing a gap between their IDs and assume that these are missing reports, when in actual fact, it is simply becasue another user has filled in this auto-incrementing gap.
I need to know if there is a way to do this in MySQL:
Is it possible that I can have a second auto-increment field called report_number which is based on a user_id field which has a different set of auto-increments per user?
e.g.
|------|---------|---------------|
| id | user_id | report_number |
|------|---------|---------------|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 1 | 4 |
| 6 | 1 | 5 |
| 7 | 2 | 2 |
| 8 | 3 | 1 |
| 9 | 3 | 2 |
|------|---------|---------------|
I am using InnoDB for this as it is quite heavily weighted with foreign-keys. It appears to complain when I add a second auto increment field, but I wasn't sure if there was a different way to do this?
MyISAM supports the second column with auto increment, but InnoDB doesn't.
For InnoDB you might create a trigger BEFORE INSERT to get the max value of the reportid and add one to the value.
DELIMITER $$
CREATE TRIGGER report_trigger
BEFORE INSERT ON reports
FOR EACH ROW BEGIN
SET NEW.`report_id` = (SELECT MAX(report_id) + 1 FROM reports WHERE user_id = NEW.user_id);
END $$
DELIMITER ;
If you can use MyISAM instead, in the documentation of MySQL page there is an example:
http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
CREATE TABLE animals (
grp ENUM('fish','mammal','bird') NOT NULL,
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (grp,id)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
('mammal','dog'),('mammal','cat'),
('bird','penguin'),('fish','lax'),('mammal','whale'),
('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;
Which returns:
+--------+----+---------+
| grp | id | name |
+--------+----+---------+
| fish | 1 | lax |
| mammal | 1 | dog |
| mammal | 2 | cat |
| mammal | 3 | whale |
| bird | 1 | penguin |
| bird | 2 | ostrich |
+--------+----+---------+
Right one with IFNULL:
DELIMITER $$
CREATE TRIGGER salons_trigger
BEFORE INSERT ON salon
FOR EACH ROW BEGIN
SET NEW.salon_id = IFNULL((SELECT MAX(salon_id) + 1 FROM salon WHERE owner = NEW.owner), 1);
END $$
DELIMITER ;
I think mysql doesnt support two auto_increment columns. you can create report number using information schema.
select NULL from information_schema.columns
MySQl does not support two auto incremented fields, if you need then create another table, set the other field which you want to be as auto incremented and you must set up a relationship with these two tables.
I have a database in MySQL. Here is SQL query to create it http://paste.org.ru/?xzctqi
Here is main table books. All I need to do is when I add some book, I choose publisher ID for it. After adding books, I need loop through all records in this table and increment column publisher_books_amount for all rows, which has same publisher as in currently added row.
+----+-------+--------+------------------------+-----------+
| id | title | author | publisher_books_amount | publisher |
+----+-------+--------+------------------------+-----------+
| 1 | Book1 | 1 | 0 | 1 |
| 2 | Book2 | 2 | 0 | 1 |
| 3 | Book3 | 1 | 0 | 2 |
| 4 | Book4 | 3 | 0 | 3 |
| 5 | Book1 | 3 | 0 | 1 |
+----+-------+--------+------------------------+-----------+
I've created trigger
DROP TRIGGER IF EXISTS `insert_trigger`;
DELIMITER |
CREATE TRIGGER `insert_trigger` AFTER INSERT ON books
FOR EACH ROW
BEGIN
UPDATE books SET publisher_books_amount = (publisher_books_amount + 1)
WHERE publisher = NEW.publisher;
END;
|
DELIMITER ;
But when I'm trying to add book, MySQL provides me with an error.
Can't update table 'books' in stored function/trigger because it is
already used by statement which invoked this stored function/trigger.
Don't ask me why do I have denormalized DB. I just need structure described above.
BTW I need to create same triggers after deleting and updating rows. If there are some problems with that, could you help me with it too?
Sincerely, Dmitriy.
Update inside a loop is not allowed, because it goes to infinite loop.
Try your triiger without update,with only set value this=this.