Is there a reason to use CURRENT_TIMESTAMP in inserts/updates? - mysql

I was using phpmyadmin to insert some dummy data into a table, and noticed it structured the insert like this:
INSERT INTO `arc`.`transactions` (
`txn_id` ,
`date_time` )
VALUES (
'50005',
CURRENT_TIMESTAMP );
Normally, I'd just not include the field "date_time" and the value is created by mySQL (as the field is of type timestamp), and auto-updates whenever you insert or update a record.
Is there any reason to structure the query as you see it above, explicitly inserting CURRENT_TIMESTAMP? Or is this a phpmyadmin oddity?

It could also be a matter of compatibility. CURRENT_TIMESTAMP is defined by the SQL standard. Automatically updated timestamp columns are not. An app that wants to be portable and record timestamps is better off explicitly specifying the currrent timestamp. And what better way to do that than to use the standard, built-in CURRENT_TIMESTAMP function?

You can have TIMESTAMP fields that don't auto-update (see the TIMESTAMP properties page for how to specify these), so depending on how you define the column, it might not be the case that an UPDATE query automatically adjusts the TIMESTAMP field.
PHPMyAdmin is probably taking the safe approach here and specifying the value to ensure it's updated, no matter the column definition. PHPMyAdmin can probably detect the default value if it wants to, so another possible explanation would be compatibility between various server versions and modes for any SQL that it generates.

It depends solely on date_time column definition. if it is like
`date_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Then you surely don't need to specify anything when inserting or updating a row, but if it is:
`date_time` TIMESTAMP NOT NULL
Then you have to specify something every time you create or update a row

Related

MySQL not executing CURRENT_TIMESTAMP updates as expected

After lots of research and several similar questions asked here, I have reached some conclusions, but as always it is, there are more questions.
This concerns the explicit_defaults_for_timestamp
Assuming the explicit_defaults_for_timestamp is turned off, this will work:
Schema:
CREATE TABLE IF NOT EXISTS `updated_tables` (
`table_name` VARCHAR(50) NOT NULL,
`updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY (`table_name`),
UNIQUE INDEX `table_name_UNIQUE` (`table_name` ASC))
ENGINE = InnoDB;
And the query:
INSERT INTO `updated_tables` (`table_name`,`updated_at`) VALUES ('products',NULL) ON DUPLICATE KEY UPDATE `table_name`=VALUES(`table_name`), `updated_at`=VALUES(`updated_at`);
First time the query is sent, the table is populated with 'products' and with the current time stamp.
If I repeat the query, then the field 'updated_at' is updated. Per definition, when I send NULL value, even though it is not allowed, the MySQL will update the column.
All is fine, and works as expected.
Lets assume I turn on the explicit_defaults_for_timestamp
If I user the above query, it will complain the the NULL is not allowed, which complies with the rules.
Question is, how can I have the same functionality with the explicit_defaults_for_timestamp turned on?
There is the solution to introduce additional column (varchar) which holds for example timestamp in miliseconds. And when I update it, then the MySQL updates the updated_at accordingly.
But it looks like an overkill, I might as well update the updated_at manually. I would like to move that responsibility to MySQL level, not doing it programatically.
In short, how can I perform updates on the table_name, and have the updated_at being set properly. The trick here is I have many updates (cache table), but actually never changing the table_name value at all.
Is it possible? Or I must turn off explicit_defaults_for_timestamp?
Is it bad decision to turn it off? Looking at this AWS RDS post seems it is ok, but I am not sure.
Side question:
If I decide to perform updates on my own, what would be the way to construct it?
Currently the MySQL CURRENT_TIMESTAMP(6) has this construct:
2018-07-10 11:32:43.490100
How could I create same construct with Javascript? First thing coming to my mind is to get current Date, and append to it last 6 digits of current timestamp.
You can create a trigger on INSERT and always set the value for updated_at with the CURRENT_TIMESTAMP - the cleanest approach but this may slow down your updates. Programmatically setting the column value would be faster than firing a trigger.
If you are executing your queries from Node.js then you can use new Date().getTime() to get a Unix timestamp in milliseconds and then construct your query like this
UPDATE tbl SET col_1 = val_1, col_2 = val_2, updated_at = FROM_UNIXTIME(js_milliseconds / 1000)
WHERE id = desired_id

Does MariaDB store a timestamp when a given row is inserted?

I am dealing with a legacy application that is using MariaDB to emulate a queue. One of the key things missing is that the original design doesn't insert the time the messages in the queue were inserted meaning that the order the messages are processed is not guaranteed.
So far the messages appear to be processed in order as we're only using a single MariaDB instance but I would like to add a created_on column to ensure this continues.
My question is that I need to backfill the created_on column and i was wondering if MariaDB stored the time a given row was inserted into the database?
I realise that unless it is in the schema it is unlikely but occasionally databases will have non-standard extensions that capture this sort of thing. Oracle for example has similar functionality to this.
MariaDB does not have a hidden timestamp. If the table has an AUTO_INCREMENT, that might suffice since you are asking for order, not specifically time.
My opinion of queuing via MySQL/MariaDB: "Don't queue it, just do it". The effort of queuing and dequeuing can become a burden, especially in end cases.
Yes you can, if you were to create a field make sure when you create the field you have the following:
create table test_created_on_table(
created_on timestamp default now() on update now()
);
If you already have a field just take off the "CURRENT_TIMESTAMP" flag on the created field. Whenever you create a new record in the table, just use "NOW()" for a value.
Or.
On the contrary, remove the 'ON UPDATE CURRENT_TIMESTAMP' flag and send the NOW() for that field. That way actually makes more sense.
This would track when row is inserted or updated.
There's another way of doing it by db trigger:
Adding a ModifiedTime
Adding a modified timestamp to a table is the most straight forward. All your have to do is create the field of type TIMESTAMP, and by default, MySQL will automatically update the field when the row is modified.
There are a couple of things to be aware of:
While you can have multiple TIMESTAMP fields in a row, only one of
these can be automatically updated with the current time on update.
If your UPDATE query contains a value for your ModifiedTime field,
this value will be used.
So, to add your modified timestamp field to an existing table, all you need is:
ALTER TABLE my_table ADD ModifiedTime TIMESTAMP;
Adding a CreatedTime
Adding a CreateTime value is a little more involved.
On the latest versions of MySQL it is apparently possible to create a DateTime field with a default value of CURRENT_TIMESTAMP. This wasn’t an option for me as I was having to support a somewhat older version, besides, even on the newer versions of MySQL it is not possible to have more than one field using CURRENT_TIMESTAMP, which of course we are in order to get ModifiedTime working.
So, in order to get a created timestamp, firstly we must add a DATETIME field to the table.
ALTER TABLE my_table ADD CreatedTime datetime NOT NULL;
Note, that this must be created as NOT NULL in order for the next part to work (this is because setting NOT NULL forces an automatic all zeros default).
Next, we must create a trigger, which will automatically be fired when we insert a value into our table and set the created timestamp.
DELIMITER //
DROP TRIGGER IF EXISTS my_table_insert_trigger//
CREATE TRIGGER my_table_insert_trigger
BEFORE INSERT ON my_table
FOR EACH ROW
BEGIN
IF NEW.CreatedTime = '0000-00-00 00:00:00' THEN
SET NEW.CreatedTime = NOW();
END IF;
END;//
DELIMITER ;
Now, when you insert a value into the table, this trigger will fire and, if you’ve not provided a CreatedTime field in your insert query, it will be set to the current time stamp.

MySQL date column auto fill with current date

I have a table where I have a date column. Is there a way for MySQL to auto fill this field whenever I insert a new registry with the current date? Or is this made automatically by default?
P.S.: I'm using PHPMyAdmin
Although it is an old post, maybe this image will help as it is more explicit:
(For phpMyAdmin users)
This configuration sets that field with a value like:
2015-12-11 07:50:47
PS: Note that the timestamp will set the time OF your server!! (i.e. the example above got the time from Pacific Time (07:50:47) but it could have been from a Spanish user at 16:50:47 local time) Keep this in mind.
Also, if you already have a "Created Date" you might need another column that updates the modification date whenever there is an update:
You only need to set on update CURRENT TIME STAMP in Attributes Field.
Ready to rock!
Set Default to in your mySql query
CURRENT_TIMESTAMP
you have to use
now()
function where you want to fill current time.
i.e.:
INSERT INTO user_rights (`user_id`,`right`,`group_id`,`created_date`) VALUES ( '42', '160', '1', now());
I realize this may not be a direct answer to the question but I do believe this is the most useable solution.
I highly recommend using a DATETIME or TIMESTAMP data type for the column in question.If you are utilizing a fairly current version of MySQL, MySQL will do the work for you.
Details:
To be very clear, as of 5.6.5, for both the TIMESTAMP & DATETIME datatypes, you can do the following:
Set a DEFAULT value of the current date & time (using NOW() or one of its aliases such as CURRENT_TIMESTAMP)This means every time you insert a new row into this table a TIMESTAMP or DATETIME column with this default will get the current date and time
Set an ON UPDATE constraint that will UPDATE a column to the current date & time when, (you guessed it) the row is updated
Here's how:
An Example in a CREATE TABLE statement:
CREATE TABLE t1 (
ts1 DATETIME ON UPDATE CURRENT_TIMESTAMP
,ts2 DATETIME DEFAULT NOW()
);
Please note that DATETIME can be replaced with TIMESTAMP for effectively the same functionality.
Additionally I suggest the use of the DATETIME data type over TIMESTAMP as DATETIME has a much larger range of dates it can support. It's worth mentioning that TIMESTAMP is smaller for those few cases that matters. For more details please read my answer here: https://stackoverflow.com/a/26117532/1748266
I have added this to my table and it works
ALTER TABLE Medewerkers ADD med_created TIMESTAMP DEFAULT now();
When you insert data into your record it update automatically the med_created
MySQL unfortunately doesn't allow specifying values other than constants as the default for columns other than TIMESTAMPs.
This is a feature available in MySQL versions 8.0+, but for older versions the only solution for a database defined default would be to use a trigger.
You can do something like this from the SQL screen
ALTER TABLE `table_name` CHANGE `created_at` `created_at` TIMESTAMP NOT NULL

MySQL Update DATETIME to DATE

I have a large table with a DATETIME column and for index reasons I want to add a column which just contains a DATE type. It seems that MySQL is not able to use an index by the following expression GROUP BY DATE(datetime) therefore I want to add another column with a second index.
For updating I use this simple statement:
UPDATE table SET datecol = DATE(datetimecol)
Now a strange behavior occurs: the datecol-column contains the correct values. But the datetimecolumn changes as well: to the current timestamp. This is the default value for this column.
I'm working now for many years with databases and MySQL but I cannot explain this behavior.
The current version is MySQL 5.1.66-0.
Do you have any suggestions or explanations for this?
Your datetimecol is not of type DATETIME, but of type TIMESTAMP which (by default) has the ON UPDATE CURRENT_TIMESTAMP attribute that automatically updates to the current time when a record is modified.
To suppress automatic properties for the first TIMESTAMP column, do either of the following:
Define the column with a DEFAULT clause that specifies a constant default value.
Specify the NULL attribute. This also causes the column to permit NULL values, which means that you cannot assign the current timestamp by setting the column to NULL. Assigning NULL sets the column to NULL.
Therefore:
ALTER TABLE my_table
MODIFY datetimecol TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
To update the records this one time without altering the values in datetimecol, you should explicitly set them to their incumbent values:
UPDATE my_table SET
datetimecol = datetimecol,
datecol = DATE(datetimecol);

How to get SQL to update my record Modified Timestamp correctly?

I am trying to set up an sql table which records when an account was created and when it was last modified. I would like sql to handle this so I don't have to do it in my php files.
I have two columns in my users table (both are of type timestamp):
created
modified
I want the "created" time to never change and always contain the date it was created, and the "modified" to be changed each time the users row is modified. I have the table set up so "created" works as I expect, but when I try to update modified:
ALTER TABLE `users`
CHANGE `modified` `modified` TIMESTAMP NOT NULL
DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP
I get the following error:
1293 - Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
Can someone assist me on what I need to do to accomplish this correctly?
It's stil not possible in mysql. You can have them set to the actual time only on INSERTs, only on UPDATEs or on both. However you couldn't have more than one of these auto-TIMESTAMP columns in one table. that's now possible using TRIGGERs if using Mysql 5.x
Refer this article It will help you lot :
Two auto-TIMESTAMP columns in one table with MySQL 5.0