mysql - timestamp column of another column value change - mysql

Say I have a mySQL table of a few columns:
id, name, job, jobUpdatedAt
Whenever specifically the job column changes, I want mySQL to automatically update the timestamp of jobUpdatedAt. (so if only name changes, it does not update)
Is such thing possible?
Thanks

CREATE TRIGGER trigger_name
BEFORE UPDATE
ON table_name
FOR EACH ROW
SET NEW.jobUpdatedAt = CASE WHEN OLD.job = NEW.job
THEN OLD.jobUpdatedAt
ELSE CURRENT_TIMESTAMP
END;
jobUpdatedAt will be renewed only when job is updated by fact.
jobUpdatedAt will be saved if the query should try to update it explicitly.
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=1b48bce653eb9a1d778e406fa5af894a

Related

Mysql update trigger except for specific column updates

In MySQL, I want to fire a trigger when update on all columns except one column update.
In my table row I have 40 columns. I want trigger to update the column update_time whenever there is an update happens on any field except update_time field.
CREATE TRIGGER `UpdateDateTrigger`
BEFORE UPDATE ON `users`
FOR EACH ROW
IF NOT UPDATE(`update_time`) BEGIN
SET new.update_timestamp = now()
END
But it is not working as expected.
By looking at MySQL automatic update for specific column instead of whole record , I've got the solution to exclude two columns update in trigger
IF !((NEW.last_visited <> OLD.last_visited) ||
(NEW.update_time <> OLD.update_time)) THEN
SET new.update_time = now();
END IF
Thank you!
Instead of having a trigger function I would like to suggest you to create the table wisely so that the update_time field gets updated automatically when something is changed associated with that row.
Please look into the documentation here for automatic update on time for each update of the row. The create syntax is simple and effective.
CREATE TABLE t1 (
// .... Other columns
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
If you want a specific control over each of your column, then writing a trigger is the best idea I think. Please check the answer here.

Trigger Update Before Or After Update On Same Table

I have this table:
Table: product
By using PHPMYADMIN, I am thinking of setting a trigger so that whenever I make changes to the price on any item, it will trigger to record the time on the price_change_time for that particular item.
My trigger is like this:
DELIMITER //
CREATE TRIGGER update_time BEFORE UPDATE ON product
FOR EACH ROW
BEGIN
UPDATE product SET price_change_time = NOW() WHERE NEW.price <> OLD.price;
END; //
DELIMITER ;
Sadly this won't work and I get:
MySQL said:Documentation
#1442 - Can't update table 'product' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
I read some of the previous asked questions and answers which is somehow related, but still not able to suit it for my case.
Anyone willing to help? My question is:
1) Is there any way to achieve what I want by just using PHPMYADMIN?
2) If Not then what is the proper way?
You can create a column in a MySQL table something like this:
CREATE TABLE product (
...
price_change_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
...
);
This creates a "magic" column in your table that gets updated to the current time whenever its row is first INSERTed or UPDATEd.
Recent versions of MySQL, but not older ones, also allow this for DATETIME columns.
You can use DATE(price_change_time) to retrieve just the date part of a timestamp.

PL SQL Trigger to update start time for row when a single column is updated

I'm fairly new to triggers and have already tried searching for a solution to my question with little results. I want to update a single row's start time column whenever it's active column is set to 1.
I have two columns ACTIVE (number) and START_TIME (timestamp) in my_table. I would like to create a PL/SQL trigger that updates the START_TIME column to current_timestamp whenever an update statement has been applied to the ACTIVE column - setting it to 1.
So far I have only seen examples for inserting new rows or updating entire tables which isn't what I'm looking to do. I'd have thought there would be a fairly simple solution to my problem.
This is what I've got so far from other examples. I know the structure of my solution is poor and I'm asking for any input to modify my trigger to achieve my desired result.
CREATE OR REPLACE TRIGGER routine_active
AFTER UPDATE ON my_table
FOR EACH ROW
WHEN (my_table.ACTIVE = 1)
begin
insert my_table.start_time = current_timestamp;
end;
\
you can use like this .it may help you
write the update query instead of insert query
CREATE OR REPLACE TRIGGER routine_active
AFTER UPDATE ON my_table
FOR EACH ROW
WHEN (new.ACTIVE = 1)
begin
update my_table set start_time =current_timestamp;
end;
I think it should be a BEFORE UPDATE, not AFTER UPDATE, so it saves both changes with a single action. Then you don't need the INSERT or UPDATE statements. I also added the "OF active" clause, so it will only start this trigger if that column was updated, which may reduce the workload if other columns get updated.
CREATE OR REPLACE TRIGGER routine_active
BEFORE UPDATE OF active ON my_table
FOR EACH ROW
BEGIN
IF active = 1
THEN
:NEW.start_time = current_timestamp;
END IF;
END;

How to submit a timestamp to a MySQL database

I have a MySQL table which hen created automatically puts a ISO 8601 timestamp into one of the fields. It does this because I have set the default value thought phpMyAdmin to TIMESTAMP.
When I update the field I want to add another timestamp to another field. Obviously I cant do that using the default option. Is there an SQL command to add a current timestamp to a field? I have had a quick read through the MySQL website but I couldnt find a way to do it...
I also had a look to see if there was a way of generating an ISO8601 timestamp through PHP but I couldnt figure out a way to convert from a PHP/unix timestamp to ISO8601.
Cheers!
MySQL can automatically initialise and/or update a single TIMESTAMP type column within every table to the current time on INSERT and UPDATE. As explained in Automatic Initialization and Updating for TIMESTAMP:
One TIMESTAMP column in a table can have the current timestamp as the default value for initializing the column, as the auto-update value, or both. It is not possible to have the current timestamp be the default value for one column and the auto-update value for another column.
In your case, because you want separate columns to hold the record's initialisation and update times, you will need to set one (or both) of those columns explicitly; one can explicitly set a date/time column to the current date/time in SQL using the NOW() function:
INSERT INTO my_table (created) VALUES (NOW());
UPDATE my_table SET updated = NOW();
One can even use triggers to achieve the automatic behaviour that is not natively provided by MySQL:
CREATE TRIGGER set_init_time AFTER INSERT ON my_table FOR EACH ROW
SET NEW.created = NOW();
CREATE TRIGGER set_updt_time AFTER UPDATE ON my_table FOR EACH ROW
SET NEW.updated = NOW();

What is the best way to set up last-modified and date-record-added fields?

Hi I would like to set and forget two fields for tracking the date the record was added and also the date the record was last modified in a mySQL database.
I am using "ON UPDATE CURRENT_TIMESTAMP" and was hoping I would just change UPDATE to INSERT.
No luck however. Can anyone give me the heads up on the best way to achieve this? - preferably inside the database itself.
This assumes MySQL 5. Simply add two triggers:
create table foo (a1 INT, created timestamp, updated timestamp) engine=innodb;
DELIMITER |
CREATE TRIGGER foo_created BEFORE INSERT ON foo
FOR EACH ROW BEGIN
SET new.created := now();
SET new.updated := now();
END;
|
CREATE TRIGGER foo_updated BEFORE UPDATE ON foo
FOR EACH ROW BEGIN
SET new.updated := now();
END;
|
DELIMITER ;
insert into foo (a1) values(7);
select * from foo;
update foo set a1=9;
You basically need both columns to be setup as timestamps with default values of CURRENT_TIMESTAMP. Unfortunately, this is not allowed in MySQL:
Error Code: 1293
Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
You can't have two timestamp columns, even though you need one to only have a default value of CURRENT_TIMESTAMP, and the other one to be UPDATE CURRENT_TIMESTAMP, this is still not allowed.
Your best bet here would be to specify as so:
CREATE TABLE `test` (
`addedDate` dateTime,
`lastModified` timestamp on update CURRENT_TIMESTAMP
)
Unfortunately, you'll have to set the 'addedDate' manually on insert using the NOW() function.
mySQL has a NOW() function you can use, see the tutorial at Tutorials Point that can help you put it in place.
You could add a DATETIME column and set it when you create the row of data. That will serve as the date the record was added.
Next, add a TIMESTAMP column:
Automatic updating of the first TIMESTAMP column in a table occurs under any of the following conditions:
You explicitly set the column to NULL.
The column is not specified explicitly in an INSERT or LOAD DATA INFILE statement.
The column is not specified explicitly in an UPDATE statement and some other column changes value. An UPDATE that sets a column to the value it does not cause the TIMESTAMP column to be updated; if you set a column to its current value, MySQL ignores the update for efficiency.
The TIMESTAMP column will take care of your record modified date.