MySQL Timestamp trigger - mysql

I am trying to set a trigger to record a timestamp in a log table when the main table is updated. I have a main table called cm and have a log table with a timestamp column.
The timestamp column in the log table is set up as follows:
ALTER TABLE log ADD COLUMN modified_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
The trigger I trying is as follows but throws this error "Error Code 1193. Unknown system variable 'modified_timestamp'
Trigger:
DELIMITER //
CREATE TRIGGER `ahrq cm`.`table_timestamp` BEFORE UPDATE ON `ahrq cm`.`ahrq_inventory_all`
FOR EACH ROW begin
set log.modified_timestamp=CURRENT_TIMESTAMP();
end
//
Can anyone shed light on this error?

Your trigger should update the log table using a normal SQL command:
DELIMITER //
CREATE TRIGGER `ahrq cm`.`table_timestamp` BEFORE UPDATE ON `ahrq cm`.`ahrq_inventory_all`
FOR EACH ROW begin
INSERT INTO log (modified_timestamp) VALUES (CURRENT_TIMESTAMP());
end
//

set is used for setting value of variables (user, system, or stored routine variables).
To update field in the log table need to issue a UPDATE query, such as
UPDATE log SET modified_timestamp = CURRENT_TIMESTAMP() WHERE ...

Related

How can I handle collision issue in Triggers?

I have a TRIGGER (before update) on a table like this:
UPDATE contact_us SET updated_at = unix_timestamp() WHERE id = new.id
And when I update a row of that table by using phpMyadmin, it throws this error:
To see it more clear:
#1442 - Can't update table 'contact_us' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
How can I fix the problem?
First of all, you do not need a trigger at all for this functionality, just use a timestamp or datetime field with automatic initialisation. So, define updated_at as follows:
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
If you insist on using a trigger for whatever reason, even then do not use a separate update statement to update the same table the trigger is defined on because that's a no go (endless loop). Use the NEW keyword to access the fields of the newly created record to modify a field's content:
set NEW.updated_at = unix_timestamp();

MySql Timestamp Trigger Preventing New Inserts

I've attempted to create a trigger to update the CREATED_DATE field of my table when a new row is inserted, but it ends up breaking the Java Application.
Basically I have an NMS that is writing to the MySql server when there is an alarm. I created the following trigger because the Java application is not applying a timestamp to alarm creation (even though there is a field for it):
CREATE TRIGGER alarm_timestamp AFTER INSERT on Alarm_Details FOR EACH ROW UPDATE Alarm_Details SET CREATED_DATE = NOW() WHERE ID = NEW.ID;
After I make this trigger, the alarms never write to the table. Then I drop the trigger and they instantly work again.
Is there a problem with the way I wrote the trigger? I'm surprised a trigger in the Sql server is preventing the application from submitting an insert query.
I have now tried to add a default value to the column with the following:
alter table Alarm_Details add constraint df_alarm_time default NOW() for CREATED_DATE;
I get a syntax error though near 'default NOW() for CREATED_DATE.'
I also tried:
ALTER TABLE Alarm_Details ALTER CREATED_DATE SET DEFAULT NOW();
It doesn't like NOW, CURRENT_TIMESTAMP, or anything. The column is set to type datetime.
I am using MySql 5.5.25.

Updating DATETIME with trigger, get error 1442 in MySQL

I am having trouble with a trigger in MySQL. I have a column named "last_modified" that I want to be automatically updated with the current date and time when it is the table is edited. Using a trigger, this is my SQL query:
delimiter //
CREATE TRIGGER trg_update_responders BEFORE UPDATE ON survey_responders
FOR EACH ROW
BEGIN
UPDATE survey_responders
SET NEW.last_modified = CURRENT_DATETIME();
END;//
However, when I update the table, such as with this query:
UPDATE survey_responders SET first_name = "bob" WHERE id = "1";
MySQL Workbench displays error 1442: "Can't update table 'table_name' in stored function/trigger because it is already used by statement which invoked this stored function/trigger"
I have looked at similar questions with the same error but still have not fixed it. Help is appreciated.
** UPDATE **
This did the trick:
delimiter //
CREATE TRIGGER trg_update_responders BEFORE UPDATE ON survey_responders
FOR EACH ROW
BEGIN
SET NEW.last_modified = CURRENT_TIMESTAMP();
END;//
Seems like I simply did not need to repeat the
UPDATE survey_responders
and CURRENT_DATETIME() did not exist, I had to use CURRENT_TIMESTAMP().
This did the trick:
delimiter //
CREATE TRIGGER trg_update_responders BEFORE UPDATE ON survey_responders
FOR EACH ROW
BEGIN
SET NEW.last_modified = CURRENT_TIMESTAMP();
END;//
Seems like I simply did not need to repeat the
UPDATE survey_responders
and CURRENT_DATETIME() did not exist, I had to use CURRENT_TIMESTAMP().
What you are trying to do is not possible using a trigger.
Within a stored function or trigger, it is not permitted to modify a
table that is already being used (for reading or writing) by the
statement that invoked the function or trigger.
Source
You need to do this some other way.
See here: MySQL - Trigger for updating same table after insert
The typical way to do that, is to create a stored procedure, that
inserts into/Updates the target table, then updates the other row(s),
all in a transaction.

MySQL Trigger cannot update table - getting ERROR 1442

I have the following trigger:
CREATE TRIGGER sum
AFTER INSERT
ON news
FOR EACH ROW
UPDATE news SET NEW.sum = (NEW.int_views + NEW.ext_views)/NEW.pageviews
It sums the int_views and ext_views column of a table and divides them by the total pageviews.
Whenever I try to add a new row to news, I get the following error:
ERROR 1442 (HY000) at line 3: Can't update table 'news' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
The trigger seems pretty simple to me. Is there a reason why the trigger fails to run?
The symptom is, that you are running an UPDATE (for all rows) inside a INSERT trigger - both modify the table, which is not allowed.
That said, if I guess the intention of your trigger correctly, you do not want to update all rows, but only the newly inserted row. You can achieve that easily with
CREATE TRIGGER sum
BEFORE INSERT
ON news
FOR EACH ROW
SET NEW.sum = (NEW.int_views + NEW.ext_views)/NEW.pageviews
Mind that this is a BEFORE INSERT trigger, as you want to change the row before it is written to the table.
If you try to update/insert on the same table that cause trigger to fire do not use the common sql command like
-> UPDATE TABLE_NAME SET COLUMN_NAME = VALUE WHERE CONDITION_LIST;
-> INSERT INTO TABLE_NAME VALUES("VALUE1","VALUE2");
This will not work. Only use set to assign the value of the column you update.
Example:
CREATE TRIGGER trigger_name BEFORE/AFTER INSERT/UPDATE ON table_name
FOR EACH ROW
SET NEW.COLUMN_NAME = "VALUE";
I was in a similar condition where I had to run two triggers:
UPDATE 3 fields on INSERTing a new ROW
UPDATE 3 fields on UPDATEing a ROW
After lot of efforts, I was finally able to write the TRIGGER in following way:
FOR updating values on INSERT
CREATE TRIGGER `INSERT_DISCOUNT_SERVICES` BEFORE INSERT ON `services`
FOR EACH ROW SET
NEW.discount_5_rate = (NEW.ndis_rate*0.05),
NEW.discount_10_rate=(NEW.ndis_rate*0.10),
NEW.discount_15_rate=(NEW.ndis_rate*0.15)
Similarly
FOR updating values on UPDATE
CREATE TRIGGER `UPDATE_DISCOUNTS_SERVICES` BEFORE UPDATE ON `services`
FOR EACH ROW SET
NEW.discount_5_rate = (NEW.ndis_rate*0.05),
NEW.discount_10_rate=(NEW.ndis_rate*0.10),
NEW.discount_15_rate=(NEW.ndis_rate*0.15)

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.