MySQL with multiple timestamps - mysql

Ok, an old hack is no longer working. Currently using MySQL 5.5.11
In my table I have the below in the same order.
created TIMESTAMP NOT NULL DEFAULT 0000-00-00 00:00:00
updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
On INSERT everything works correctly and NOW() is inserted on both created and updated
Now with MySQL 5.5.11 when I UPDATE, updated works correctly but I loose created (reverts back to 0000-00-00 00:00:00)
How can I overcome this limitation with MySQL's lack of multiple TIMESTAMP support?

Yes, it would work on earlier version, but not newer version.
I believe you can solve this as follows:
`created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
And then create an trigger BEFORE UPDATE on [updated] column.
SET new.updated = now();
Or vice-versa.

As far as I understand it, TIMESTAMP columns get automatically updated on every UPDATE operation to a particular row. It looks like you need column created to be DATETIME instead of timestamp.

Related

mariadb/mysql - How to make a date column with sysdate/curdate?

I want to make a column in my table that has the equivalent functionality as the oracle sysdate variable as the default value. So when a row is inserted (without the date, the current sysdate is used). what is the query to create this table?
Also should I allow nulls for this column, how would that work?
Also, I want to be able to insert a row into this table, such that the functionality occurs. Please provide sample insert query that uses this functionality.
Also, I want to be able to do the same for the DATETIME column type.
Thanks in advance.
This is pretty well explained in the documentation:
TIMESTAMP and DATETIME columns can be automatically initializated and
updated to the current date and time (that is, the current timestamp).
The syntax looks like:
create table t (
. . .,
createdAt datetime not null default current_timestamp
);
If you are giving the column a default value, then you might as well declare it as NOT NULL.
You can also do the same thing for updates:
updatedAt datetime not null default current_timestamp on update current_timestamp

mysql datetime default 0001-01-01 00:00:00 on update 0001-01-01 00:00:00

I have a table, let's call it employees, that sends data to a web server, whenever this happens a datetime field is updated with a current_timestamp.
Now, when a record changes, I want to reset the datetime field to 0001-01-01 00:00:00 so that it will send the new information again.
Is it possible to do something like
DEFAULT 0001-01-01 00:00:00 ON UPDATE 0001-01-01 00:00:00
instead of
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
on update only supports current_timestamp; no other value is allowed. See Automatic Initialization and Updating for TIMESTAMP and DATETIME:
Use of DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP is specific to TIMESTAMP and DATETIME. The DEFAULT clause also can be used to specify a constant (nonautomatic) default value; for example, DEFAULT 0 or DEFAULT '2000-01-01 00:00:00'.
You can either use an after update trigger, but the common solution is to use another column and set the value to current_timestamp on export and compare that to the latest update:
create table tablename (
...
updated_at datetime(6) default current_timestamp(6)
on update current_timestamp(6),
exported_at datetime(6) default '0001-01-01 00:00:00'
)
To get all rows that needs to be exported, use
select * from tablename where exported_at <> updated_at for update;
To mark something as updated after an export, you then use
update tablename set exported_at = current_timestamp(6);
(Everything inside a transaction of course)
Thanks to #Lightness Races in Orbit for pointing out that it's not obvious why to use datetime(6) instead of datetime: per default, mysql uses datetime with second precision. That is usually not a problem - but for this application of detecting changes it would miss updates that were applied within 1 second of the export, and thus would have a slightly different effect than "resetting the column on every update to a value that marks that update". This only works for mysql 5.6.4 and above. Prior to that, use a trigger if you need that precision.

How to create 2 auto-set timestamp columns in a MySQL table?

I want a MySQL table of mine to contain 2 timestamp columns, both set automatically without the client side help: one to be initialized once on insert:
`added` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
and another initialized the same on insert and updated on every update:
`updated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
But this doesn't work this way:
[Err] 1293 - Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
Is there a known workaround?
There is not just a workaround, there is a solution: Upgrade to MySQL 5.6.5 or higher and this is supported.
See: MySQL 5.6.6 TIMESTAMP columns and DEFAULT values
{edit} Since upgrading is not an option, you can make the first column a normal timestamp column and create a trigger that sets one timestamp when you insert the record. Then you can create the other colum with the DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, so it gets a timestamp on insertion and on update.
CREATE TRIGGER task_creation_timestamp BEFORE INSERT ON tasks
FOR EACH ROW
SET NEW.created = NOW();
I've stolen this trigger from this answer.
There is no "solution" as the error suggest, you can ONLY HAVE ONE TIMESTAMP per table (On previous versions of 5.6.6 as GolezTrol Suggested)
To workaround this i suggest you make of the "timestamps" a datetime and set the default to NOW() or CURRENT_TIMESTAMP() or any other synonym for NOW()

MySQL column type "TIMESTAMP" implicitly includes "NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"

I've just spent a couple of hours tracking down this bug. Given the following SQL:
DROP DATABASE IF EXISTS db;
CREATE DATABASE db;
CREATE TABLE db.tbl (t1 TIMESTAMP) ENGINE=INNODB;
SHOW CREATE TABLE db.tbl;
The last line shows me:
'CREATE TABLE `tbl` (
`t1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1'
Where on earth does the NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP come from? I didn't write any of that, and I very much do not want any of that, and I'm kinda lost for words that MySQL would make such a presumption.
Do I have some insane obscure configuration option turned on/off? Is this default behavior? It is a bug? In any case, how do I make MySQL behave sanely?
In MySQL 5.6.5 there are several updates regarding this initialization, you can see on this link (Automatic Timestamp Properties Before MySQL 5.6.5).
If you're using MySQL <= 5.6.5, in order to ignore this initialization you need to set the DEFAULT value to 0 or NULL with NULL allowed.
CREATE TABLE tbl
(
field1 TIMESTAMP DEFAULT 0,
field2 TIMESTAMP NULL DEFAULT NULL
)
If you're using MySQL >= 5.6.6, there is parameter called explicit_defaults_for_timestamp which is disabled by default. You can enable this setting or set the DEFAULT value to 0 or NULL, same approach for previous MySQL versions.
If you're using MySQL >= 8.0.2, then explicit_defaults_for_timestamp is enabled by default. This disables the non-standard behaviour (thankfully). Also, MySQL generates a warning when you disable this setting. So, for instance, if you don't define DEFAULT value for a TIMESTAMP column, it is automatically set to NULL.
Thos are default values which are being used even if not explicitly stated in the CREATE statement. If you want to avoid both, use t1 TIMESTAMP DEFAULT 0 or ts1 TIMESTAMP NULL DEFAULT NULL
Update
Prior to MySQL 5.6.5 you could only use TIMESTAMP in case you wanted to have column that is automatically updated when row is changed. Unfortunately this functionality was limited to MyISAM and isn't available on InnoDB tables.
MySQL 5.6.5 allows this with DATETIME as well. See other posts on this site for more details

MySQL timestamp only on create

I use timestamp on MySQL 5.x (with PHP) to remember event times. During development I had to update the table with a query that changes something in all columns. The timestamp was then reset to current time.
How can I make timestamp change only on inserts and not on updates or replace?
Here's all you need to know. In short, though, I think this should do it:
ALTER TABLE `mytable`
CHANGE `mydatefield` `mydatefield`
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
Very good documentation here for time-stamp.
You can use a default value for that field and not include it in the insert or update query.