Trying to create a field in a table that will get the old value of another field. My table is very similar to this:
------------ -------------------- ------------------------
| id int(10) | price decimal(5,2) | price_old decimal(5,2) |
----------------------------------------------------------
What I am trying to get is the value of price field to get copied in price_old field ON UPDATE of the current record.
Is it possible to achieve this only with mysql?
PS: The data contained in that cell is not critical. The usage is to store the previous price of a item and after to be able to show how it changed. I will only need the last value, not the full history of the table entry. (My MySQL server is 5.0, if this matters)
Yes, you can use a BEFORE UPDATE trigger (documentation).
I think this syntax is right but haven't used MySQL in a while so you may have to toy with it. If it's wrong and you get it working please let me know so I can edit it.
DELIMITER $$
CREATE TRIGGER `price_trigger`
BEFORE UPDATE ON `products`
FOR EACH ROW
BEGIN
IF NEW.price != OLD.price
SET price_old = OLD.price;
END IF;
END$$
DELIMITER ;
Use triggers on update rule. There set value of price to price_old
CREATE TRIGGER `update_price_old`
BEFORE UPDATE ON `table_name` FOR EACH ROW
BEGIN
UPDATE `table_name` SET price_old = OLD.price where OLD.id = id;
END
Related
I have a users_settings table on my db in which I store some data about the user. For some of that data I need to keep track of last modification, for example:
+--------------+-------------+
| Field | Type |
+--------------+-------------+
| feel | varchar(10) |
| feel_last | timestamp |
| other | varchar(10) |
| other_last | timestamp |
+--------------+-------------+
When I update the row with a new feel value I want to automatically write the current timestamp, is it possible to achieve this directly from mysql or I need to set the timestamp directly in the update query from my backend?
Update 1
As suggested I need to use a trigger, I written this trigger but there is some syntax error, can you help me to identify the error?
CREATE TRIGGER users_feel_last BEFORE UPDATE ON users
FOR EACH ROW BEGIN
IF NEW.feel <> OLD.feel THEN
SET NEW.feel_last := now();
END IF;
END;
UPDATE 2
For who use AWS RDS: the parameter "log_bin_trust_function_creators" isn't enabled by default, to create triggers it's necessary, here a small guide to set it: https://aws.amazon.com/it/premiumsupport/knowledge-center/rds-mysql-functions/
Now, thanks to James answer I created the trigger, it works well
DELIMITER $$
CREATE TRIGGER before_feel_last_update
BEFORE UPDATE ON users
FOR EACH ROW
BEGIN
if(old.feel<>new.feel)
then
set new.feel_last=current_timestamp;
elseif( old.feel = NULL )
then
set new.feel_last=current_timestamp;
end if;
END$$
DELIMITER ;
A trigger is not necessary in MySQL. This functionality is happily built in. You can define the table as:
create table users (
. . .,
update_datetime datetime default current_timestamp on update current_timestamp
);
You can read about this default in the documentation.
You can use the below trigger on BEFORE UPDATE
BEGIN
if(old.feel<>new.feel)
then
set new.feel_last=current_timestamp;
end if;
END
I need to track who changes to a table in mySQL database. Would you please give me an idea how I can determine which of my application users makes changes to a record in a table?
I assume you have a table with 2 columns that their name is colmun1 and column2 You should add modified_by column and also add this trigger:
DELIMITER |
CREATE TRIGGER before_update_sometable
BEFORE UPDATE ON sometable FOR EACH ROW
BEGIN
IF (NEW.column1 <> OLD.column1 or NEW.column2 <> OLD.column2) THEN
NEW.modified_by = user();
END IF;
END;
|
DELIMITER ;
MySQL doesn't currently support updating rows in the same table the trigger is assigned to since the call could become recursive. Does anyone have suggestions on a good workaround/alternative? Right now my plan is to call a stored procedure that performs the logic I really wanted in a trigger, but I'd love to hear how others have gotten around this limitation.
Edit: A little more background as requested. I have a table that stores product attribute assignments. When a new parent product record is inserted, I'd like the trigger to perform a corresponding insert in the same table for each child record. This denormalization is necessary for performance. MySQL doesn't support this and throws:
Can't update table 'mytable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. A long discussion on the issue on the MySQL forums basically lead to: Use a stored proc, which is what I went with for now.
Thanks in advance!
You can actually up the rows in the same table as the trigger. The thread you linked to even has the solution.
For example:
TestTable ( id / lastmodified / random )
create trigger insert_lastmod
before insert on TestTable
for each row
set NEW.lastmodified = NOW();
insert into TestTable ( `random` ) values ( 'Random' );
select * from TestTable;
+----+---------------------+---------------------+
| id | lastmodified | random |
+----+---------------------+---------------------+
| 1 | 2010-12-22 14:15:23 | Random |
+----+---------------------+---------------------+
I suppose you could call the stored proc in your trigger. HOwever, if you want to update some fields in the same records that you are changing (such as an updatedby or lastupdated column) then you can do this in a beofre trigger according to the refernce manual. http://dev.mysql.com/doc/refman/5.0/en/trigger-syntax.html
This is a common operation for triggers and I find it difficult to believe it isn't supported.
If you want to update column that you don't read in trigger function, then as a workaround, you could put that column into separate table.
You can actually do that
The below is an example for same
DELIMITER $$
create trigger test2
before insert on ptrt
for each row
begin
if NEW.DType = "A" then
set NEW.PA = 500;
elseif NEW.DType = "B" then
set NEW.PA = 1000;
else
set NEW.PA = 0;
END IF;
END;$$
DELIMITER;
This worked for me :D
On Before / Update.
BEGIN
SET NEW.DateTimeUpdated = NOW();
END
I'm new to the creation of triggers but I need it since I'm using a persistent storage for some IDs.
I have the table RECEIPT with a column RECEIPT_ID
and the table CONFIG_DB with columns and values:
NAME VALUE
--------------- -----
NEXT_RECEIPT_ID 1
and I created this trigger
CREATE TRIGGER UPDATE_RECEPCION_ID
AFTER INSERT ON RECEIPT
FOR EACH ROW
BEGIN
UPDATE CONFIG_DB SET VALUE=VALUE+1;
END
;
I don't know if this is OK... all I want its that after I insert a new RECEIPT_ID the VALUE in CONFIG_DB increases by 1. Thank you very much.
EDIT: I work in Mysql Workbench 5.2.40 with Mysql Server 5.5.25
Use following query to create trigger
delimiter |
CREATE
TRIGGER `UPDATE_RECEPCION_ID`
AFTER INSERT ON `RECEIPT`
FOR EACH ROW BEGIN
UPDATE CONFIG_DB SET VALUE=VALUE+1
WHERE NAME='NEXT_RECEIPT_ID';
END;
|
I understand how to fill a field with random values, but I need my field to automatically update with a random value for each new column. For some reason, I'm having trouble figuring out how to do this.
By the way, as it says above, this is for a database in MySQL.
Thanks everyone
You can use a trigger to update a specific colum after insert like this:
DELIMITER |
CREATE TRIGGER randtrigger AFTER INSERT ON your_table
FOR EACH ROW BEGIN
UPDATE your_table SET some_column = rand()
WHERE id = NEW.id;
END;
|
DELIMITER ;