Sql Trigger to insert updated record into another table - mysql

i've been looking though different tutorials online,but i can't seem to find what i need.
I need to copy a record into a history table, every time it is updated.
Is there a way to do it with triggers without having to type out all of my data fields?

It would help if you posted a schema of your tables, and what exactly you want to be inserting into your history table, but for now I'll make some assumptions about the table you're updating, and what you want in your history table. As an aside, this trigger will not work for a copy-paste... as each subsequent update to a record will be unable to be inserted into your history table because of primary key violations.
CREATE TRIGGER trg_History AFTER UPDATE ON my_table
FOR EACH ROW INSERT INTO history_table VALUES (NEW.col1, NEW.col2, OLD.col1, OLD.col2 ... etc)
the NEW keyword refers to all the data being inserted/updated and OLD refers to, well, the old data before being overwritten.
Again, please be more specific with the information you need to be inserting, and what you've tried so far, as we can only help you with general syntax at this point in time.

Related

Duplicates data after joining trigger table with other tables

I want to fetch the BEFORE and AFTER data from TableProduct whenever there is an update. So I created a Before and After trigger queries in which the respected values from the trigger is stored in separate tables titled TableProduct_Before and TableProduct_After.
My challenge is I always get duplicates result whenever I try to INNER JOIN the three tables.
I have tried the DISTINCT and ORDER BY ID command but still the same challenge.
I made enquiry I was told I can't join trigger table values because it doesn't have a foreign key, I tried adding a foreign key but it didn't work saying foreign key already exists in TableProduct.
Please, I will appreciate any help thank you.
You are misunderstanding how triggers work. You can use either a before or after trigger.
The key is using new and old. Inside the body of the trigger, you have both the old and new values. In pseudocode, this looks like:
insert into archive (pk, old_value, new_value)
values (new.pk, old.value, new.value);
Both OLD and NEW data is available in both before and after trigger.
The difference is - BEFORE trigger fixes the attempt to update whereas AFTER fixes successful attempt result. I.e. BEFORE is executed anycase (but its changes may be rollbacked!), rather than AFTER.
See https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=dd19c611c7e2fbef88b2133dcaa61dfa
PS. Recent MySQL versions allows triggers chains - a lot of triggers on the same event fired one-by-one. So check that your saving trigger is the most last in this chain.

Why not to delete tho old row and insert updated row?

I have a table (MySql) that some rows need to be updated when a user desires.
i know the right way is just using Sql UPDATE statement and i don't speak about 'Which is faster? Delete and insert or just update!'. but as my table update operation needs more time to write a code (cause of table's relations) why i don't delete the old row and insert updated field?
Yes, you can delete and insert. but what keeps the record in your database if the program crash a moment before it can insert data to Database?
Update keeps this from happening. It keeps the data in your database and change the value that needed to be changed. Maybe it is complicated to use in your database, but you can certain that your record still safe.
finally i get the answer!
in a RDBMS system there are relations between records and one record might have some dependencies. in such situations you cannot delete and insert new record because foreign key constraint cause data lose. records dependent (ie user posts) to main record (ie an user record) will be deleted!
if there are situations that you don't have records dependencies (not as exceptions! but in data models nature) (like no-sql) and you have some problems in updating a record (ie file checking) you can use this approach.

What is proper way to set and compare variable inside an sql trigger

Am populating a table using a trigger after an insert event occurs on another table and that worked fine. However i then noticed that the trigger would still insert a new row for existing records. To fix this, I want to create the trigger again but this time it would only fire if a condition is met...but not having previously used triggers in the past am getting a syntax error and not able to identify what am doing wrong. Kindly have a look and help me fix this
CREATE TRIGGER `students_gen_insert`
AFTER INSERT ON `students` FOR EACH ROW
BEGIN
INSERT INTO records (student_id, subject_id)
SELECT new.student_id, subjects.subject_id
FROM subjects
WHERE category = new.class;
END;
Am currently using MySql 5.6.17 version.
It is generally not a good idea to SELECT from the table the trigger is on, and forbidden to UPDATE or INSERT (not that you are doing those). Assuming you are trying to get the values for the row just inserted, the first SET ... SELECT you have is needless; just use NEW.fieldname to get the fields of the inserted row.
The second SET ... SELECT and following condition are a bit confusing. If referential integrity is being maintained, I would think it would be impossible for the records table to refer to that particular student_id of the students table at the point the trigger is executed. Perhaps this was to avoid the duplicate inserts from the trigger's previous code? If so, it might help for you to post that so we can pinpoint the actual source of redundant inserts.

Insert data to table with existing data, then delete data that was not touched during session

I am making bunch of INSERT ON DUPLICATE KEY UPDATE to a table filled with data.
I need to fill table with that data AND remove data that I haven't filled (I mean remove rows that was not mentioned in my INSERTs).
What I tried and what was working:
create new timestamp column in table
During INSERTs insert or update this column with CURRENT_TIMESTAMP, so that all rows I touched have newest timestamps
Run delete query that deletes all rows that are older than the starting time of my script.
This idea works perfectly, but there is one problem: my replication binary log get filled with unnececary data on both modes (ROW and STATEMENT). I don't need that timestamps at all to be replicated...
I don't want to do TRUNCATE TABLE before inserts because my app should deliever a non-stop access to data (old or new). If I do TRUNCATE TABLE tables can be without data for some time.
I can also save all primary key values that I insert in scripts memory or temporary table, and then delete the rows that are not in that table, but I hope there is a more optimized and clever way to do that.
Do you have any idea how can I achieve that goal so I can update data, delete only untouched rows and replicate only changes (I guess in ROW mode)?
I'm not very familiar with replication binary logs, sorry in advance if won't work. I assumed that logging can be set differently for tables.
I would do the following:
create a table for the new data with the same primary key column with
the old table
delete all rows from old table where not found in the new table
update rows in the old table according to the new table
This way wouldn't be unnecessary log inserts.
This assumes that you have the required space in the server, but can work.

TRIGGER: Read NEW.values and OLD.values during "ON DUPLICATE KEY UPDATE"

I'm trying to write a mini-auditing system for individual tables in MySQL.
I had good luck working with basic INSERT/UPDATE/DELETE commands, however now a table I'm interested in auditing uses INSERT ... ON DUPLICATE KEY UPDATE.
By using a trigger ON BEFORE INSERT I can tell this event is occurring, however I can only get half the data I'm interested in. NEW.values are readily available, but I've no idea how to get the OLD.values that came before. I suppose I could do a query using the NEW.ID in existing table, but I'm not sure about performance and reliability.
I need the OLD.values because I'm storing both old and new values for each change event since I read somewhere that was a good idea for collapsing data etc...
Is there a way in MySQL 5.0 (or newer GA release) to reliably retrieve these values as though I were in an UPDATE trigger?
EDIT: Another wrinkle:
Looks like the NEW.values do not match the data after update. They match the INSERT statement not the ON DUPLICATE KEY UPDATE data that will actually go into the record.
It looks like the trigger event ON AFTER UPDATE also catches the ON DUPLICATE KEY UPDATE change. From here, I was able to get OLD/NEW values and perform the logging I needed to perform.