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.
Related
I have not used MySQL in a few years and when I created a new table it did something I was not expecting. I am using MariaDB v5.5.60-MariaDB
I need to create a table that has both a created column and an updated column.
I need the created column to only be set to CURRENT_TIMESTAMP when the row is created and then never change unless I change it explicitly.
I need the updated column to be set to CURRENT_TIMESTAMP both when the row is created and when the row is changed.
If I do the following:
CREATE TABLE user_prefs (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
user VARCHAR(255) NOT NULL,
provider VARCHAR(255) NOT NULL,
pref VARCHAR(128) NOT NULL,
jsondata LONGTEXT,
created timestamp NOT NULL,
modified timestamp NOT NULL,
PRIMARY KEY (id),
UNIQUE INDEX id_UNIQUE (id ASC));
Then the created column is set to:
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
and the modified column is set to:
DEFAULT '0000-00-00 00:00:00'
If I try this:
CREATE TABLE user_prefs (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
user VARCHAR(255) NOT NULL,
provider VARCHAR(255) NOT NULL,
pref VARCHAR(128) NOT NULL,
jsondata LONGTEXT,
created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
modified timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE INDEX id_UNIQUE (id ASC));
Then I get the error **Error Code: 1293. Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
**
So is there a way to automate setting both created and modified on creation of a row and then to change modified every time the row is change?
Thanks in advance.
A table might have automatic initialization of date in only one column in old versions of MySQL. But its behavior fixed in version 5.6.5.
It means you have several ways to avoid this error:
1.You can upgrade your MySQL to the latest version;
Advantages:
native clear implementation of modification dates management in a database side
there aren't excess triggers
Вrawback:
if the current version of MySQL is used in exists projects then upgrading might make some problems.
2.You can create triggers for updating and the creation of a record, as #Simonare said
Advantages:
implementation of modification dates management in a database side
Вrawback:
there are many excess triggers. You'll create two triggers for each table. It means you'll create N*2 triggers for N tables.
3.You can set default value of created column to 0000-00-00 00:00:00 and set default value of updated column to CURRENT_TIMESTAMP(). In this case date of updating will be generated automatically. Also if you write null to created column MySQL will generate current date automatically and set it to the column. For example:
CREATE TABLE example_table (
created TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
updated_at TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP
);
If you execute the following query:
INSERT INTO example_table (created) VALUES (null);
created column will have current date value. MySQL will fill it automatically.
Advantages:
there aren't excess triggers
Вrawback:
implementation of modification dates management in a database side and client application side
4.You can use automatic initialization of date in updated column and use trigger to fill created column. For example:
CREATE TABLE example_table (
created TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
updated_at TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP
);
DELIMITER //
CREATE TRIGGER example_table_set_created_date
BEFORE INSERT
ON example_table FOR EACH ROW
BEGIN
SET NEW.created = CURRENT_TIMESTAMP();
END; //
DELIMITER;
Advantages:
implementation of modification dates management in a database side
Вrawback:
there are many excess triggers. You'll create N triggers for N tables.
you can create trigger for this
DELIMITER //
CREATE TRIGGER user_prefs_before_insert
BEFORE INSERT
ON user_prefs FOR EACH ROW
BEGIN
SET NEW.updated = new.created;
END; //
DELIMITER ;
then another trigger for update
DELIMITER //
CREATE TRIGGER user_prefs_before_update
BEFORE UPDATE
ON user_prefs FOR EACH ROW
BEGIN
SET NEW.updated = CURRENT_TIMESTAMP();
END; //
DELIMITER ;
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
I have this table with newspost, i want to add timestamps on date added, and i want to update another col when the post is edited. I would like it to happen automaticly in MySql. without the use of any PHP code.
CREATE TABLE IF NOT EXISTS news (
id int(11) NOT NULL AUTO_INCREMENT,
data text,
date_published timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
date_edited timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
What's the best practice in a case like this?
Consider using triggers. From the MySQL docs:
A trigger is a named database object that is associated with a table, and that activates when a particular event occurs for the table. Some uses for triggers are to perform checks of values to be inserted into a table or to perform calculations on values involved in an update.
Example of a trigger:
CREATE TRIGGER trigger_example AFTER UPDATE ON news
FOR EACH ROW UPDATE some_table SET another_column = NEW.data;
You can only use the DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP features on one timestamp column in a table.
Use the following table definition to turn off the features for date_published and use them for date_edited:
CREATE TABLE IF NOT EXISTS news (
id INT(11) NOT NULL AUTO_INCREMENT,
data TEXT,
date_published TIMESTAMP NOT NULL DEFAULT 0,
date_edited TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
When inserting a new row, pass a NULL value for date_published to automatically assign the current timestamp to that column.
MySQL Docs on Automatic Initialization and Updating for TIMESTAMP:
It need not be the first TIMESTAMP column in a table that is
automatically initialized or updated to the current timestamp.
However, to specify automatic initialization or updating for a
different TIMESTAMP column, you must suppress the automatic properties
for the first one. Then, for the other TIMESTAMP column, the rules for
the DEFAULT and ON UPDATE clauses are the same as for the first
TIMESTAMP column, except that if you omit both clauses, no automatic
initialization or updating occurs.
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.
Following is my SQL query, it throws an error:-
CREATE TABLE IF NOT EXISTS USER_PROFILE(Id INT PRIMARY KEY AUTO_INCREMENT, date DATETIME NOT NULL DEFAULT NOW) ;
It says Invalid default value for 'date'.
I've tried synonyms for NOW() as well, namely CURRENT_TIMESTAMP, but still the same error.
How can I create a column date with default value current time?
On the documentation page, it says to assign this way
CREATE TABLE t1 (
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
dt DATETIME DEFAULT CURRENT_TIMESTAMP
);
From the document
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 TIMESTAMP
and DATETIME columns
So no function is allowed in the default value hence the first query is failing.
Again from the document
As of MySQL 5.6.5, TIMESTAMP and DATETIME columns can be automatically
initializated and updated to the current date and time (that is, the
current timestamp). Before 5.6.5, this is true only for TIMESTAMP, and
for at most one TIMESTAMP column per table. The following notes first
describe automatic initialization and updating for MySQL 5.6.5 and up,
then the differences for versions preceding 5.6.5.
Before 5.6.5, this is true only for TIMESTAMP
So your mysql version is less than 5.6.5 hence the 2nd query is failing too.
So you need to create the table as
CREATE TABLE IF NOT EXISTS
USER_PROFILE
(
Id INT PRIMARY KEY AUTO_INCREMENT,
date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ;
It might be that DATE, as a reserved word, is confusing it by the time it gets to the DEFAULT clause. Try a different name and if that works, try quoting "date".
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