I am working on some database project (PHP/MySQL) used for billing.
Whenever a new bill is created I want to generate a bill number consisting of year, week and increment number. I would like to do this with a trigger. The trigger will use the existing billnumbers to find the increment number or start with a fresh increment for the first bill n a new week and/or new year.
Apart from generating the bill number, I can do a BEFORE INSERT trigger and set the NEW.billnumber to the newly generated billnumber. It is also possible to do an AFTER INSERT and update the record with the generated billnumber.
My question is which one should I choose. BEFORE INSERT or AFTER INSERT? I did search for this, but I can't find a good argumentation when to use BEFORE or AFTER.
Found out that it can be done with BEFORE INSERT only because MySQL does not allow manipulation of the table that triggered the AFTER INSERT trigger.
Related
Hey guys a little question for you.
I'm currently working on SQL Triggers and my goal is to archive logging if there are changes made to our database. For example we got some tables like customers with: name, firstname, placeofbirth and so on. We offer the users to update their own data and want to save the OLD data in a new table for logging reasons. To have only one logging table for all updates the logging table is kind of generic with:
id, timestamp, table_name, column, old_value, new_value.
table_name is the updated table, colum the updated column in this table and all the rest should speak for itself. Therefore it would be great to know not only in which tuple but also in which particular column the update has happened.
My question: Is there a construct like:
create trigger logging_trigger on customer**.firstname** after insert ...
to trigger an action only if there happened an update on let's say the 'firstname' column?
If not is there a smooth solution for handling all possible update cases?
Thank you.
I use a format like you described in my system... Below is how I accomplish it with your required logic.
CREATE DEFINER = CURRENT_USER TRIGGER `testing_schema`.`new_table_BEFORE_UPDATE` BEFORE UPDATE ON `new_table` FOR EACH ROW
BEGIN
IF NEW.ColumnName <> OLD.ColumnName THEN
INSERT INTO HistoryTable (`ColumnName1`, `ColumnName2`, ect..) VALUES (OLD.ColumnName1, OLD.ColumnName2, ect...);
END IF;
END
The main difference In mine is, that I do not have an IF condition. I simply copy the entire row to the history table every time an Update/Delete is made to that row. That way I don't have to maintain any form of logic to handle scenarios of investigating "what changed", I just save the entire row because I know "something" changed.
I have a MySQL table myTable with 4 columns id,name,version and date. Everyday I get the data and this data changes only when they install new version of our products.
I would like to analyze the change in version numbers over time, to analyze when and how many customers are installing this new version.
For example,
INSERT INTO MYtABLE (ID,NAME,VERSION,DATE) VALUES (1, 'ABC','1.0','07/21/2016');
INSERT INTO MYtABLE (ID,NAME,VERSION,DATE) VALUES (1, 'ABC','1.0','07/22/2016');
INSERT INTO MYtABLE (ID,NAME,VERSION,DATE) VALUES (1, 'ABC','1.1','07/23/2016');
In this case, because of change in version from 1.0 to 1.1 I would like to capture the name, id, date of 07/23/2016.
Here is my question:
How do i implement this in MySQL?
to implement Change Data Capture? I'm new to this and I couldn't find any tutorials as well.
I can think of Creating a trigger which captures this change. But it involves performance overhead.
Or a SELECT will work here?
Any better solns?
I can bear the performance! So upon insert, how do we compare the values to capture this change? Or How do I track these changes?
Trigger is the best solution here.
There is another solution that you can schedule a script that run on every minutes or every 5 minutes and capture the data change.
I have a table named Warehouse for my database, it has Warehouse_idWarehouse and Warehouse_name as primary keys. What i want to do is to efficiently store a maximum of N recent changes that have been made to each warehouse that is stored in the table. I have considered creating a "helper" table (e.g. warehouse_changes) and taking care of the updates through my application, but honestly it feels like there is a smarter way around this.
Is there a way to store a specific amount of entries per warehouse and automatically manage updating the right element through mysql workbench? Thanks in advance and keep in mind that i'm not particularly advanced in this field.
There is a very detailed article on O'Reilly Answers that describes how to do exactly what you want using triggers.
When explained in two words, you need to create a helper table and a trigger per each operation type that you want to store. For example, here's how a trigger for updates looks like according to that article:
-- Creating a trigger that will run after each update
-- for each affected row
CREATE TRIGGER au_warehouse AFTER UPDATE ON Warehouse FOR EACH ROW
BEGIN
-- Insert new values into a log table, or you can insert old values
-- using the OLD row reference
INSERT INTO warehouse_log (action, id, ts, name)
VALUES('update', NEW.id, NOW(), NEW.name);
END;
After that you can get the latest 1000 changes using a simple SQL query:
SELECT * FROM warehouse_log ORDER BY ts DESC LIMIT 1000;
I am working on a legacy system that generates confirmation numbers based on the ID of their order record in the database. It's just a bunch of zeros append to the front of the row ID which is created automatically using auto increment. Currently the system is inserting the order into the database and then immediately doing an update to add the confirmation number (after getting the insert ID programmatically).
I'd like to reduce this second step if at all possible by adding the confirmation number when the order is placed. However, I am unaware of how this can be done, or if it can be done, via SQL. Is this possible? If so, how? I've Googled this but I just get results telling me how to get the last insert ID after the query has already run.
You can write a trigger that is execute where order is inserted.
Sample:
CREATE TRIGGER order_zeros BEFORE INSERT ON orders
for each row
begin
SET NEW.confirmation = LPAD( NEW.id, 8, '0' );
end;
Disclaimer: this code is not tested, only to explain solution.
I have a situation where I need to keep track of all changes to the data in a MySQL database.
For example, we have a field in the "customers" table which will contain a rating that indicates how risky it is to do business with that customer. Whenever this field is changed, I need to have it logged so we can go back and say "well they were a 3 and now they are an 8," for example. Is there any automated way to handle this in MySQL or am I just going have to write tons of change tracking logic into the application itself?
This is the type of thing that triggers are designed for inside of MySQL assuming you're using a 5+ version of MySQL.
CREATE TRIGGER log_change_on_table BEFORE UPDATE ON customers
FOR EACH ROW
BEGIN
INSERT INTO customer_log (customer_id, rating, date)
VALUES (OLD.customer_id, OLD.rating, now())
END $$