Timestamp in MySQL not updating despite updating records - mysql

I have a column which contains a timestamp in my MySQL database. No matter how many times I update my records, my timestamps are not updated. Is there anything I should do to make it auto update?
Searching other questions here in Stackoverflow, most of them say the opposite, it's really very confusing! For example, this one, Should I use field 'datetime' or 'timestamp'? (Look at the top rated answer)
Thank you
Here is my table structure
+----------------+-------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+-------------------+----------------+
| Num | int(11) | NO | PRI | NULL | auto_increment |
| mem_name | varchar(50) | NO | | NULL | |
| mem_id | int(11) | NO | | NULL | |
| car_number | varchar(11) | NO | | NULL | |
| firstcall_time | timestamp | NO | | CURRENT_TIMESTAMP | |
| tow_time | datetime | NO | | NULL | |
+----------------+-------------+------+-----+-------------------+----------------+
6 rows in set (0.00 sec)
One Record:
+-----+----------+--------+------------+---------------------+---------------------+
| Num | mem_name | mem_id | car_number | firstcall_time | tow_time |
+-----+----------+--------+------------+---------------------+---------------------+
| 1 | Jakey | 54564 | SHA34345 | 2013-02-19 16:14:12 | 2013-02-19 16:32:45 |
+-----+----------+--------+------------+---------------------+---------------------+
1 row in set (0.00 sec)
After Updating:
+-----+----------+--------+------------+---------------------+---------------------+
| Num | mem_name | mem_id | car_number | firstcall_time | tow_time |
+-----+----------+--------+------------+---------------------+---------------------+
| 1 | Tommy | 54564 | SHA34345 | 2013-02-19 16:14:12 | 2013-02-19 16:32:45 |
+-----+----------+--------+------------+---------------------+---------------------+
1 row in set (0.00 sec)

The main reason that your timestamp is not updating beacuse you have not added ON UPDATE CURRENT_TIMESTAMP clause in your table creation statement.
Change it with alter table command and modify your column
With both DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP,
the column has the current timestamp for its default value and
is automatically updated to the current timestamp.
You must add On UPDATE CURRENT_TIMESTAMP
CREATE TABLE t1 (
id int, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP);
Edit - Table modifying command
alter table <tablename> modify <columnName> TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Refer http://dev.mysql.com/doc/refman/5.0/en/timestamp-initialization.html

Add On UPDATE CURRENT_TIMESTAMP
MySQL Query:
ALTER TABLE `table_name` CHANGE `date_field` `date_field` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
Hope it helps !

Related

MySQL gives incorrect DateTime Value for some dates but not others

I have a table that looks like this in MySQL:
mysql> describe sale;
+-------------+------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------+------+-----+-------------------+-----------------------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| salesperson | int(11) | NO | MUL | NULL | |
| customer | int(11) | NO | MUL | NULL | |
| product | int(11) | NO | MUL | NULL | |
| count | int(11) | NO | | NULL | |
+-------------+------------+------+-----+-------------------+-----------------------------+
Now if a run this statement, I get an ERROR 1292:
mysql> insert into `sale` values (25860,'2006-04-02 02:30:50',1,25,2,21);
ERROR 1292 (22007): Incorrect datetime value: '2006-04-02 02:30:50' for column 'timestamp' at row 1
However, if I just change the date by one day, the statement works:
mysql> insert into `sale` values (25860,'2006-04-03 02:30:50',1,25,2,21);
Query OK, 1 row affected (0.00 sec)
What is the magical thing about the second of April 2006? I can't detect any problems with the format specified. I also tried retyping the statement to make sure it was not caused by invisible characters.
Daylight Saving Time.
On 2006-04-02 at 2am the clock jumped to 3am. So there was no 02:30:50

MySQL INSERT shows more affected rows than affected

Consider the following three queries.
The first one can only return a single row as bids_buy.id is the primary key.
The second one shows an existing record in entities_has_documents for primary key 3099541982-2536988132, and the third one doesn't execute due to that existing record.
The forth one does execute as expected, but shows two affected rows.
Why does it show two affected rows, and not just one associated with primary key 3099541982-2536988132?
mysql> SELECT bb.bids_sell_id, 2536988132,"pub_bids", NOW(),506836355 FROM bids_buy bb WHERE bb.id=2453409798;
+--------------+------------+----------+---------------------+-----------+
| bids_sell_id | 2536988132 | pub_bids | NOW() | 506836355 |
+--------------+------------+----------+---------------------+-----------+
| 3099541982 | 2536988132 | pub_bids | 2016-04-16 08:19:13 | 506836355 |
+--------------+------------+----------+---------------------+-----------+
1 row in set (0.00 sec)
mysql> SELECT * FROM entities_has_documents;
+-------------+--------------+----------+---------------------+--------------+-----------+------------+-----------+-------------+
| entities_id | documents_id | type | date_added | date_removed | added_by | removed_by | purged_by | date_purged |
+-------------+--------------+----------+---------------------+--------------+-----------+------------+-----------+-------------+
| 2453409798 | 2536988132 | pub_bids | 2016-04-16 08:07:13 | NULL | 506836355 | NULL | NULL | NULL |
| 3099541982 | 2536988132 | pub_bids | 2016-04-16 08:18:53 | NULL | 506836355 | NULL | NULL | NULL |
+-------------+--------------+----------+---------------------+--------------+-----------+------------+-----------+-------------+
2 rows in set (0.00 sec)
mysql> INSERT INTO entities_has_documents(entities_id,documents_id,type,date_added,added_by)
-> SELECT bb.bids_sell_id, 2536988132,"pub_bids", NOW(),506836355 FROM bids_buy bb WHERE bb.id=2453409798;
ERROR 1062 (23000): Duplicate entry '3099541982-2536988132' for key 'PRIMARY'
mysql> INSERT INTO entities_has_documents(entities_id,documents_id,type,date_added,added_by)
-> SELECT bb.bids_sell_id, 2536988132,"pub_bids", NOW(),506836355 FROM bids_buy bb WHERE bb.id=2453409798
-> ON DUPLICATE KEY UPDATE type="pub_bids", added_by=506836355, date_added=NOW(), removed_by=NULL, date_removed=NULL;
Query OK, 2 rows affected (0.00 sec)
Records: 1 Duplicates: 1 Warnings: 0
mysql> EXPLAIN bids_buy;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| id | int(10) unsigned | NO | PRI | NULL | |
| bids_sell_id | int(10) unsigned | NO | MUL | NULL | |
| stage_buy_id | int(10) unsigned | NO | MUL | NULL | |
+--------------+------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> EXPLAIN entities_has_documents;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| entities_id | int(10) unsigned | NO | PRI | NULL | |
| documents_id | int(10) unsigned | NO | PRI | NULL | |
| type | varchar(16) | NO | MUL | NULL | |
| date_added | datetime | NO | | NULL | |
| date_removed | datetime | YES | | NULL | |
| added_by | int(10) unsigned | NO | MUL | NULL | |
| removed_by | int(10) unsigned | YES | MUL | NULL | |
| purged_by | int(10) unsigned | YES | MUL | NULL | |
| date_purged | datetime | YES | | NULL | |
+--------------+------------------+------+-----+---------+-------+
9 rows in set (0.01 sec)
mysql>
EDIT
Per http://php.net/manual/en/pdostatement.rowcount.php
If the last SQL statement executed by the associated PDOStatement was
a SELECT statement, some databases may return the number of rows
returned by that statement. However, this behaviour is not guaranteed
for all databases and should not be relied on for portable
applications.
So, am I just seeing the number or rows returned from my SELECT statement, and not the number or rows affected by my INSERT? Why would MySQL do such a thing?
EDIT DONE
I think it is due to ON DUPLICATE KEY UPDATE modifier as the MYSQL Reference Manual 5.5 as well as MySQL Reference Manual 5.7 says
If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, an UPDATE of the old row is performed. The affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values. If you specify the CLIENT_FOUND_ROWS flag to mysql_real_connect() when connecting to mysqld, the affected-rows value is 1 (not 0) if an existing row is set to its current values.”.
In your case you already had a row with primary key value 3099541982-2536988132. Hence the MySQL lets you know that you are trying to insert a row with duplicate Primary or Unique key by indicating 2 rows affected. As the manual also say that ON DUPLICATE KEY UPDATE leads to the sequence of INSERT than UPDATE update command in case of duplicate key whereas it executes only the INSERT command in case the key is not present.
I hope this helps.
UPDATE
Also see this link.

Create table with date column

I want to create a student table with column 'student_birthday' and its format should be dd-mm-yy.
create table `student`.`studentinfo`(
`student_id` int(10) not null auto_increment,
`student_name` varchar(45) not null,
`student_surname` varchar(45) not null,
`student_birthday` date(???),
(some lines of code)
primary key(student_id));
what should be inputted in the (???) to get the right format above?
Just use "DATE" without the brackets. The brackets are only needed for certain column types where you want to specify the maximum number of bytes/characters that can be stored.
For MySQL, it's documented at https://dev.mysql.com/doc/refman/5.7/en/date-and-time-types.html
The following example will explain your problem. I am using MySQL 5.7.18.
Firstly I have described the structure of users table as I am going to create posts table with FOREIGN KEY.
Later I created posts table and it has a DATE field named created with many other columns.
Finally I inserted 1 row in the newly created table.
mysql> desc users;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| id | bigint(20) | NO | PRI | NULL | |
| fname | varchar(50) | NO | | NULL | |
| lname | varchar(50) | NO | | NULL | |
| uname | varchar(20) | NO | | NULL | |
| email | text | NO | | NULL | |
| contact | bigint(12) | NO | | NULL | |
| profile_pic | text | NO | | NULL | |
+-------------+-------------+------+-----+---------+-------+
7 rows in set (0.00 sec)
mysql> CREATE TABLE posts(id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, title text NOT NULL, description text NOT NULL, posted_by bigint, FOREIGN KEY(posted_by) REFERENCES users(id) ON DELETE CASCADE ON UPDATE RESTRICT , created DATE);
Query OK, 0 rows affected (0.01 sec)
mysql> desc posts;
+-------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| title | text | NO | | NULL | |
| description | text | NO | | NULL | |
| posted_by | bigint(20) | YES | MUL | NULL | |
| created | date | YES | | NULL | |
+-------------+------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql> INSERT INTO posts(title, description, posted_by, created) values("Getting started with MySQL", "Excellent Database system", 1, "2017-05-26");
Query OK, 1 row affected (0.00 sec)
mysql> select * from posts;
+----+----------------------------+---------------------------+-----------+------------+
| id | title | description | posted_by | created |
+----+----------------------------+---------------------------+-----------+------------+
| 1 | Getting started with MySQL | Excellent Database system | 1 | 2017-05-26 |
+----+----------------------------+---------------------------+-----------+------------+
1 row in set (0.00 sec)
mysql>
The datatype date on its own is enough to represent a date value. The format will matter when you are displaying the data, for which you can use the FORMAT function on your date column.
I should add that there is a certain amount of flexibility as to the format when inserting date time literals as documented here.

mysql trigger when no match found

I'm trying to setup a mysql trigger. So lets assume the table is like this
mysql> explain users;
+------------+-------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| purge_date | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+-------------+------+-----+-------------------+-----------------------------+
and
mysql> explain users_details;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
so the trigger i have setup will create a purge_date of NOW on the users table when something is removed from the users_details table. This is fine.
The issue is that sometimes the data for the users_details table comes through incorrectly and then the users update it so then i need to remove the purge_date if they re-insert the data. Now I have made this trigger
CREATE TRIGGER purge_fix AFTER INSERT ON users_details
FOR EACH ROW
BEGIN
UPDATE users
SET purge_date= '0000-00-00 00:00:00'
WHERE users.name = NEW.name;
END;
Which works fine but in some situations there will not be a link between the users_details table and the users table (it will be created at a later stage) so my question is, as the trigger will fail in some situations (which is 100% fine by me), will I be breaking something having the trigger failing?

MySQL default value error with ON DUPLICATE KEY UPDATE

Why am I getting this error? Did something change with MySQL versions which would cause this (which worked at one point) to now fail? The INSERT INTO does not specify the user_id value which would be required if an insert was done, but since id 1 already exists, this should become an UPDATE and be valid.
mysql> select * from article;
+----+---------+---------------------+-----------+-----------+
| id | user_id | published_at | title | content |
+----+---------+---------------------+-----------+-----------+
| 1 | 1 | 2011-12-10 12:10:00 | article 1 | content 1 |
| 2 | 2 | 2011-12-20 16:20:00 | article 2 | content 2 |
| 3 | 1 | 2012-01-04 22:00:00 | article 3 | content 3 |
+----+---------+---------------------+-----------+-----------+
3 rows in set (0.00 sec)
mysql> desc article;
+--------------+------------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+-------------------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| user_id | int(11) unsigned | NO | MUL | NULL | |
| published_at | datetime | NO | | CURRENT_TIMESTAMP | |
| title | varchar(100) | NO | | NULL | |
| content | text | NO | | NULL | |
+--------------+------------------+------+-----+-------------------+----------------+
5 rows in set (0.01 sec)
mysql> INSERT INTO article (id)
-> VALUES (1)
-> ON DUPLICATE KEY UPDATE title = 'article 1b', content = 'content 1b';
ERROR 1364 (HY000): Field 'user_id' doesn't have a default value
MySQL version 5.6.12.
You're getting error because
The user_id column is defined as NOT NULL
The user_id column doesn't have a default value specified
You don't specify its value in your query either
PS: the question is irrelevant to the ON DUPLICATE KEY UPDATE clause - it would be the same error if you didn't use it as well.
PPS: regardless of if the ON DUPLICATE KEY UPDATE triggered - your insert should satisfy all the constraints
Set a default value to the user_id table with: ALTER TABLE article
ADD user_id int(11) NOT NULL DEFAULT {DEFAULT_VALUE}
or change from NOT NULL to NULL