MYSQL Change Values based on Table values (Constraint or Trigger?) - mysql

Quick few questions on MYSQL syntax, it seems extremely hard to find these answers on google. Is it possible to set a constraint or trigger so that when a value of a column reaches a certain point it get's reset and something else is done. Or also if say hourLog is greater than zero, then licence status changes from Default value of INVALID to Valid.
I know all this could be done with a program that was using the database, but was just curious if there were MYSQL commands to do this automatically with a trigger or a Constraint.
Sorry if this was posted, I just was looking for quick clarification for a class.

You could use these two triggers, one for the UPDATE, one for the INSERT:
CREATE TRIGGER upd_yourtable BEFORE UPDATE ON yourtable
FOR EACH ROW
SET new.licenseStatus=
CASE WHEN new.hourLog>0 THEN 'Valid' ELSE 'INVALID' END
;
CREATE TRIGGER ins_yourtable BEFORE INSERT ON yourtable
FOR EACH ROW
SET new.licenseStatus=
CASE WHEN new.hourLog>0 THEN 'Valid' ELSE 'INVALID' END
;
Please see fiddle here.

Related

How to set a MySQL Trigger the correct way

i have a database table that gets updated via a CMS. Sometimes, there is one field that gets updated and then another field should get updated as well. I tried to get this done by just modifying the php code of the CMS, where the value gets saved in the DB. The problem is, with every update of the CMS this is gone.
I came across MySQL Triggers and i think this is a good way to do this. So whenever this field is updated, it should also update the other field with a value that will always be the same. But i cant quite get my head around the syntax, to get this going...
I tried:
CREATE TRIGGER after_unique_content_update
AFTER UPDATE
ON articles FOR EACH ROW
BEGIN
IF OLD.date <> new.date THEN
INSERT INTO release=2020
END IF;
END
But it is not working. So what i try to do: Every time in the CMS someone changes the date, the release for that db entry should be set to 2020. The standard for release is NULL. With the above trigger, nothing happens after the date is changed... Never worked with Trigger or Events in MySQL before...
How can i set the release to 2020 when the date field for that entry is updated?
Thanks for your help in advance!
best regards
CREATE TRIGGER before_unique_content_update
BEFORE UPDATE
ON articles
FOR EACH ROW
SET NEW.release = CASE WHEN OLD.date <> NEW.date
THEN 2020
ELSE NEW.release
END;
Firstly the condition is checked by the trigger, and, if the condition matched, new value to the column is set to 2020 (or, maybe, it's better to set it not to 2020 but to YEAR(CURRENT_DATE)?). If the condition not matched then the value is not altered (assigned value is the same as current one).
After the trigger performs this task, actual table data update is performed.
AFTER UPDATE trigger is not applicable - when it fires the data in the table is already set to the value specified in a query.

SQL Trigger not on rows but on attributes

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.

MySql trigger, update another table on insert

I've already, searched and read, many answers about this issue , but couldn't get a clear answer on how to do this.
My query is the following:
DELIMITER //
CREATE TRIGGER `Stock_Update` AFTER INSERT ON `Store_db`.`Product_Supply` FOR EACH ROW
BEGIN
UPDATE `Store_db`.`Stock` AS `ST`
SET `ST`.`Stock_Quantity` = `ST`.`Stock_Quantity` + `Product_Supply`.`Supply_Quantity`
WHERE `ST`.`Product_ID` = `Product_Supply`.`Product_ID`;
END//
DELIMITER ;
Thanks In Advance.
P.S. A More Generic Answer would be nice too and might be helpful for others as well
From within a trigger on a given table, all references to fields of this table must be prefixed by either NEW. or OLD., which refers respectively to the value of this field after or before the change.
In your case, you probably want to add the newly inserted quantity to your existing stock: use NEW.Supply_Quantity (do not mention Product_Supply, this is already implied by the NEW keyword).
Likewise, you certainly want to use NEW.Product_ID in your condition.
Notice that NEW is not available in a trigger on deletion, like OLD in a trigger on insertion.

Update mysql table with same values and still get a timestamp update

So I have this stamp timestamp DEFAULT NOW() ON UPDATE NOW() row on my table, and I need it to update even when the update I'm executing is basically same data on all fields.
Is there any way of doing this within the declaration of the table, like some other option other than on update, or do I have to force a stamp = now() every time I update (and remove the on update of course since it will be useless).
I've seen this thread, but it only answers what is happening and why, not how to get around it other than forcing it indirectly
As #veeTrain said, it'd be easy if you added it to your update statement. This is just another way of doing it, you can also use unix_timestamp().
UPDATEtable_nameSETlast_logged_in= unix_timestamp() WHEREid= '$user_id'
I know my response is late, but I ran into a similar issue and figured I'd share my solution for those encountering this thread in the future.
You'd have to use a trigger to force it each time.
DELIMITER GO
CREATE TRIGGER `mydb`.`mytable_U` BEFORE UPDATE ON `mydb`.`mytable`
FOR EACH ROW
BEGIN
SET NEW.stamp = CURRENT_TIMESTAMP;
END
GO
DELIMITER ;
I find it easier to just do the following as part of your update statement:
UPDATE table_name SET last_logged_in = NOW() WHERE `user_id`...
This way the value is always updated and if nothing else has changed the timestamp still gets updated. Thanks for your question; it was the same as mine.

MySQL Trigger - INSERT on condition of UPDATE

I'm trying to find the most effecient way of inserting data into another table when a particular field is updated on trigger table. The INSERT should only occur on a specific type of update.
The table on which I want to create the trigger is named incremental. The table I'm inserting into is named crm_record
On incremental there is a field called status. By default when a record is initially added to the table the status field is set to new. After billing has processed that value changes to processed. So once this occurs I want to INSERT into crm_record, only if the value of another field (success) is set to 1.
I have considered using both CASE and IF but would like an expert's opinion on the best way to do this.
Ok, I eventually went with this that seemed to work. Thanks for pointing me in the right direction
CREATE TRIGGER `incremental5_after_ins_tr_crmm` AFTER UPDATE ON `incremental5`
FOR EACH ROW
BEGIN
IF Status = 'processed' AND Success = 1 THEN
INSERT INTO crm_master (msisdn,source,contract_type,revenue) VALUE (new.msisdn,'INC5',new.contract_type,revenue=revenue+2.5)
ON DUPLICATE KEY UPDATE contract_type=new.contract_type,revenue=revenue+2.5;
END IF;
END;
All you need to do is to create an AFTER UPDATE trigger and test the value of status and success together. If it's going only going to be one state you're testing for then an IF statement would be the simplest way to go about it.
However before implementing a trigger it's always worth going back a step and checking to see if the row in crm_record shouldn't actually be inserted via the code logic when the status and success columns are updated.