I want to save the mysql query used to delete a row in a table:
Example:
CREATE TRIGGER `table_DEL` BEFORE DELETE ON `table`
FOR EACH ROW BEGIN
INSERT INTO db_bk.table
SELECT *,NOW(),QUERY()
FROM db.table
WHERE table_id= OLD.table_id;
END
As you understand, I want to now if exists a query() function or another method to retrieve the query that activate the trigger (the exact delete query)
Thank you very much
As #devart said - such a function doesn't exist. If you are worried about who will delete from your table then restrict the 'delete' permission to one account. Then you can control how records are removed and when.
Related
I have a mysql Innodb table 'classrooms_subjects' as
id|classroom_id|subject_id
classroom_id & subject_id are composite keys. Whenever i insert a row with classroom_id & subject_id, my id field is inserted as 0.
Now i want to create a trigger which will enter id field as last_inserted_id()+1.
Also I need to take care of multiple records inserted at a time. My trigger is like below:
CREATE TRIGGER `increment_id` AFTER INSERT ON `classrooms_subjects`
FOR EACH ROW BEGIN
UPDATE classrooms_subjects
SET classrooms_subjects.id = LAST_INSERT_ID() + 1 WHERE id=0;
END
when i am inserting a record I am getting the error as:
"Cant update table in trigger because it is already used by statement which invoked this trigger
For general info: using an update statement inside the trigger isn't right.
Better to use a before insert trigger and simply assign the value of your column using NEW.id
http://dev.mysql.com/doc/refman/5.7/en/trigger-syntax.html
A column named with OLD is read only. You can refer to it (if you have
the SELECT privilege), but not modify it. You can refer to a column
named with NEW if you have the SELECT privilege for it. In a BEFORE
trigger, you can also change its value with SET NEW.col_name = value
if you have the UPDATE privilege for it. This means you can use a
trigger to modify the values to be inserted into a new row or used to
update a row. (Such a SET statement has no effect in an AFTER
trigger because the row change will have already occurred.)
You should probably structure your table to make the auto_increment work properly. Better a solution that works when multiple sessions are inserting to the DB at once.
There is a declared MySQL function GETUSERID() returning an integer value. How to make a record insert faster: setting the value from inside a query like
INSERT INTO ttable
(idtoset, some_other_field...)
VALUES (GETUSERID(), value1...);
or call
INSERT INTO ttable
(some_other_field...)
VALUES (value1...);
and fill idtoset by a trigger that fires before insert?
What if the query is performing multiple row insert like
INSERT INTO ttable
(idtoset, some_other_field...)
VALUES (GETUSERID(), value1...),
(GETUSERID(), value2...),
...
(GETUSERID(), valueN...);
?
Edit
I have just investigated the answer of #Rahul.
I created a ttest table with two triggers
CREATE TRIGGER `tgbi` BEFORE INSERT ON `ttest` FOR EACH ROW BEGIN
SET NEW.testint=1;
END;
CREATE TRIGGER `tgbi` BEFORE UPDATE ON `ttest` FOR EACH ROW BEGIN
SET NEW.testint=2;
END;
If I am not mistaken, should the before insert trigger call UPDATE SET the second trigger is expected to fire as well and the created testint value might be =2, but it is =1 in every inserted row. Could that mean that the engine optimises INSERT procedure and sets the value simultaneously with that set manually by query?
Appended on request of #Rick-James. The question is not about the definite function. It is actually about any function. Any function will be called same number of times if the record is inserted from trigger or from INSERT query. That is why I am wondering what is better from the point of MySQL engine - to call it manually setting the value in inserted records or filling it by means of triggers?
CREATE DEFINER=`***`#`***` FUNCTION `GETUSERID`() RETURNS int(10)
BEGIN
DECLARE id_no INT DEFAULT -1;
SELECT `id` INTO id_no FROM `tstuff`
WHERE `tstuff`.`user_name`=
(SELECT SUBSTRING_INDEX(USER(), '#', 1)) LIMIT 1;
RETURN id_no;
END
What is faster? No idea since I haven't done a bench marking on that but doing an direct INSERT operation would better to my knowledge instead of inserting and then perform an UPDATE through trigger.
Does what you are doing currently not working? you can as well make it a INSERT .. SELECT operation like
INSERT INTO ttable (idtoset, some_other_field...)
SELECT GETUSERID(), value1..., valuen FROM DUAL;
In past versions of MySQL, using a before insert trigger to populate a not nullable column didn't work as MySQL was evaluating the provided columns before the trigger. That's why whenever I have such a situation, I usually tend to go with functions instead of triggers.
From a performance point of view, since the before insert trigger is evaluated before actually writing data so the time needed to perform this is almost the same as immediately getting the value with the function and without trigger. But if all you are doing in the trigger is set the user ID, then I really see no reason to use a trigger.
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
I want to run this query each time a new row is added or deleted
UPDATE brandnames updated
JOIN (select bname, count(*) as cnt
from brandnames
group by bname) aggregate
ON updated.bname= aggregate.bname
set `count`= aggregate.cnt
Please help me with a trigger entry for this. Thanks,
I'd say you cannot:
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.
I am wondering if it is possible to perform a SQL query then update another table with the generated ID and continue through all of the rows?
I have this SQL query that works but what I need to do is after each row is added to cards to then update merged.cars_id with the last generated ID so they are linked. normally I would do this with PHP but ideally I would like to just do it with MySQL if possible.
MAIN QUERY
INSERT INTO cards (first_contact_date, card_type, property_id, user_id)
SELECT first_contact_date, 'P', property_id, user_id FROM merged
THEN I NEED WITH MATCHING ROWS (Roughly)
UPDATE merged SET merged.card_id = LAST_INSERT_ID (FROM ABOVE) into the matching record..
Is something like this possible and how do I do it?
I would recommend using MySQL triggers to do this
http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html
A trigger is a function that will be executed AFTER or BEFORE the INSERT or DELETE or UPDATE is done over any record of your table.
In your case you need to do a AFTER INSERT on cards that just updates the merged table. Make sure its AFTER insert as you wont be able to access the new row's ID otherwise.
The code would look something like this, assuming the id field from the cards table its named "id"
delimiter |
CREATE TRIGGER updating_merged AFTER INSERT ON cards
FOR EACH ROW BEGIN
UPDATE merged SET card_id = NEW.id;
END;
|
delimiter ;
May I suggest Stored Procedures?
http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html
--EDIT--
Ah yes, triggers. For this particular situation, Jimmy has the answer. I will leave this post for the sake of the link.
I would set up a trigger to do this. For mysql, read http://dev.mysql.com/doc/refman/5.0/en/triggers.html. This is what triggers are designed to handle.