I think I may have encountered a bug in mysql, or is it just me doing it wrong.
I've been using the same specific queries for the last four months and just today it stopped working somehow. I can't see the problem.
I'm executing these queries in the mysql console it works great, and the field is being updated. but when these queries are being executed by PHP it fails.
After insertion of a record into a table(with two timestamp fields), I'm trying to update a specific timestamp column.
But unfortunately it fails to update the column.
The query goes well(no errors), but still the value in the timestamp column stays the same. That's weird, cause when I'm leaving the initial column value as NULL, the update query succeed.
Columns :
START_DATETIME, END_DATETIME - are "timestamp" type.
Insert:
INSERT INTO TABLE1(START_DATETIME, END_DATETIME, RESPONSE)
VALUES(NOW(), NOW(), 'STARTED')
Insert is done successfully. id is 123
The update query is normal like any other query:
UPDATE TABLE1
SET END_DATETIME = NOW(), RESPONSE='ENDED'
WHERE ID = 123
Update fails, END_DATETIME doesn't get the NOW() value.
Can be reproduced with this:
CREATE TABLE TABLE1
(
id int auto_increment,
start_datetime timestamp,
end_datetime timestamp,
response varchar(100),
primary key(id)
);
You probably have defined the first timestamp column (the START_DATETIME one) to be auto-inserted and auto-updated with the CURRENT_TIMESTAMP value (which is the same as NOW().
Notice that if you don't explicitedly state anything about the TIMESTAMP columns in the CREATE TABLE script, the first one of them gets by default this behaviour/attributes. Read the MySQL documentation about this Automatic Initialization and Updating for TIMESTAMP, where it states:
With neither DEFAULT CURRENT_TIMESTAMP nor ON UPDATE CURRENT_TIMESTAMP, it is the same as specifying both DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP.
So, if you do a SHOW CREATE TABLE tableName, you'll have something like this:
CREATE TABLE table1
( ...
, START_DATETIME TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP
, ...
) ;
You should alter the column definition to not be auto_updated, if you don't want this behaviour:
ALTER TABLE table1
MODIFY COLUMN
START_DATETIME TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP ;
After looking into this more this is what I'd expect if the first table has ON UPDATE CURRENT_TIMESTAMP as it is being automatically set by the update to the second record.
I don't think that this can have been working previously;
to fix it:
ALTER TABLE TABLE1
CHANGE COLUMN start_datetime start_datetime TIMESTAMP NULL DEFAULT NULL AFTER id,
CHANGE COLUMN end_datetime end_datetime TIMESTAMP NULL DEFAULT NULL AFTER start_datetime;
If you want date time values the TIMESTAMP isn't much good for this as it is useful for auto-updating values as the TIMESTAMP data type offers automatic initialization and updating to the current date and time. For more information, see Automatic Initialization and Updating for TIMESTAMP
If you need a field you can manage yourself then one of the other types
DATE
DATETIME
may be more appropriate, see 11.3.1. The DATE, DATETIME, and TIMESTAMP Types
This is a problem with timestamp type, If you change both the column to datetime, you will get what you are expecting
Related
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
I have a table with a few dates (among other things) that look like this:
CREATE TABLE message (
created_on DATEIMTE NOT NULL DEFAULT CURRENT_TIMESTAMP,
send_on DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
modified_on DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
status CHAR NOT NULL DEFAULT 'V',
status_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
...
);
When I do an INSERT INTO, I generally do not define the modified_on field since the default makes sense. I may change the send_on value if I do not want my message to be sent immediately.
So an insertion could look like this:
INSERT INTO message
(send_on)
VALUES ('2017-08-31 14:31:22');
Later, the user may ask to change the send_on field. At that point, I run an UPDATE statement as follow:
UPDATE message
SET send_on = <user-defined-date>,
modified_on = CURRENT_TIMESTAMP
WHERE id = 123;
This case is fine since I modified only one date.
Now, at the time the user makes a modification, I may have to also change the status field. That would translate into something like this:
UPDATE message
SET send_on = <user-defined-date>,
modified_on = CURRENT_TIMESTAMP,
status = <new-status>,
status_date = CURRENT_TIMESTAMP
WHERE id = 123;
In that last UPDATE statement and less obvious, in the INSERT INTO statement above, I am setting more than one DATETIME field to the value CURRENT_TIMESTAMP (2 in that UPDATE, 3 in the INSERT INTO through the DEFAULT definitions).
My question is: will all the columns assigned the value CURRENT_TIMESTAMP always receive the exact same value whenever it gets used more than once? Or will each column determine the value of CURRENT_TIMESTAMP once it gets executed and hence, could be a second later (if we were a few ms away from the next second, it can easily happen.)
So far I have not seen a problem, but that does not mean it could not happen. Is that specific case properly documented somewhere in the MySQL reference?
According to the documentation,
NOW() returns a constant time that indicates the time at which the statement began to execute. (Within a stored function or trigger, NOW() returns the time at which the function or triggering statement began to execute.) This differs from the behavior for SYSDATE(), which returns the exact time at which it executes.
So current_timestamp (which is a synonym for now()) will have the same value even if the query runs for hours. It is so relevant that it will actually even keep that value if the query gets replicated to a different server.
I have a table with two timestamp fields. They are not nullable. The problem is that whenever I insert null into those fields, the current date is automatically saved, instead of throwing an error saying "Column 'first_data_dt' cannot be null", just like it happens when I insert a value into another non-nullable field.
There are no triggers associated to this table.
Does anybody know why this is happening?
EDIT to add table definition:
CREATE TABLE `ui_mytable` (
`id` int(11) NOT NULL,
`first_data_dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`last_data_dt` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I understand now why first_data_dt is updated to the current timestamp anytime I insert null. But what about last_data_dt?
That's what a TIMESTAMP column does:
The TIMESTAMP data type offers automatic initialization and updating to the current date and time (that is, the current timestamp). [...] You can initialize or update any TIMESTAMP column to the current date and time by assigning it a NULL value, unless it has been defined with the NULL attribute to permit NULL values.
Source: MySQL documentation
Maybe you want to use a DATETIME instead?
I believe I have set my 5.6.17 ver MySQL server to recognize IANA TZ Databases as evidenced by
a system_time_zone variable being set to "Pacific Daylight Time"
a time_zone variable being set to UTC
NOW(), giving me a standard SQL format date time
I thought that that would be sufficient to create an auto updating time stamp field, but, if I create a table via:
CREATE TABLE test (
id SERIAL,
stamp TIMESTAMP,
stuff VARCHAR(255)
);
INSERT INTO test ( stuff ) VALUES ( 'abc' );
SELECT * FROM test;
records seem to be created with NULL in the stamp field:
id stamp stuff
1 NULL abc
I thought that maybe the date gets entered only when doing an update, but when I update:
UPDATE test SET note = 'xyz' WHERE id = 1;
still the stamp is NULL
id stamp stuff
1 NULL xyz
I attempted to change the create as
stamp TIMESTAMP DEFAULT NOW(),
which provides a proper value, but the stamp field remains unchanged when I update (even minutes later).
I also attempted to use
stamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
which, also, gave me an initial value, but never changed when updating.
Also, attempting to append AUTO_INCREMENT didn't seem to work for me. Did I mention that I'm a MySQL newb?
How do I force my TIMESTAMP field to fill at creation and modify when updated?
A field with type TIMESTAMP is also just another field without any special properties like auto initialization or update.
DEFAULT CURRENT_TIMESTAMP only sets the current timestamp when you create the row.
You are looking for the property ON UPDATE CURRENT_TIMESTAMP. This will set the timestamp each time you update the row, given that at least one of the row's values actually changes.
For more infos, have a look at the MySQL docs regarding Automatic Initialization and Update for TIMESTAMP.
Bottom line, create your table like this and stamp will always give you the timestamp of the last change:
CREATE TABLE test (
id SERIAL,
stamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
stuff VARCHAR(255)
);
Sorry can't comment without enough reputation, and I don't know what is IANA TZ Database
But you can try to add On update CURRENT_TIMESTAMP when you create the table:
CREATE TABLE test (
id SERIAL,
stamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`
stuff VARCHAR(255)
)
it is quite simple
update table set fieldname=now() where fieldname = value;
here we assume that field we try to update is timestamp type field
If I create a table with an entity that is suppose to be DATE and when I Insert and leave that column blank shouldn't it display the current date? Same with time?
For example...
CREATE TABLE Register
(
Name CHAR(20) NOT NULL,
Date DATE,
Time TIME
);
Then I Insert:
INSERT INTO Register (Name)
VALUES ('Howard');
I want it to display on the table:
Howard | 5/6/2014 | 8:30 PM
But instead it displays:
Howard | NULL | NULL
Is this incorrect and if so what am I suppose to Insert to allow the current date and time of insert to display?
Firstly, you should have a PRIMARY KEY in your table.
Secondly, you have not set default values for columns Date and Time. Also, you can't set them separately for the DATE and TIME types – you should use TIMESTAMP type and DEFAULT CURRENT_TIMESTAMP like :
CREATE TABLE Register (
Name CHAR(20) PRIMARY KEY NOT NULL,
Date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Thirdly, if you want to use exactly two columns for date storing, you can set a trigger on INSERT event for this table, like it is shown below :
CREATE TRIGGER default_date_time
BEFORE INSERT ON my_table_name
FOR EACH ROW
BEGIN
SET NEW.Date = CURDATE();
SET NEW.Time = CURTIME();
END;
$$
You need to set a default. So you might think you could do this:
CREATE TABLE Register
(
Name CHAR(20) NOT NULL,
Date DATE DEFAULT CURRENT_DATE,
Time TIME DEFAULT CURRENT_TIME
);
But that won’t work. You need to use CURRENT_TIMESTAMP and change your DB structure to use the combined TIMESTAMP format:
CREATE TABLE Register
(
Name CHAR(20) NOT NULL,
Timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
The reason being is there is no MySQL DEFAULT value for DATE or TIME alone. Some clues to that behavior here:
The DEFAULT value clause in a data type specification indicates a
default value for a column. With one exception, the default value must
be a constant; it cannot be a function or an expression. This means,
for example, that you cannot set the default for a date column to be
the value of a function such as NOW() or CURRENT_DATE. The exception
is that you can specify CURRENT_TIMESTAMP as the default for a
TIMESTAMP column. See Section 11.3.5, “Automatic Initialization and
Updating for TIMESTAMP”.
Here are two options:
Get rid of Date and Time columns and add time stamp
INSERT INTO Register (Name,Ctime) VALUES ('Howard',CURRENT_TIMESTAMP);
If you want to continue with your table structure
INSERT INTO Register (Name,Date,Time) VALUES ('Howard',CURDATE(), CURTIME());
Also Note that date and time are reserved words of MySQL and hence should be quoted with backticks to avoid conflicting with reserved words. Or just rename it according to a table name format.