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.
Related
I executed the following query on my mysql server:
CREATE TABLE user(
created_at timestamp NOT NULL,
updated_at timestamp NOT NULL,
id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
count integer NOT NULL,
name varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_general_ci
When I looked into phpmyadmin I was suprised.
The created_at column had a default set to CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP was also there.
How can this even happen?
It shouldnt do that, right?
Although this behavior is surprising to me, it is actually explained in the documentation:
For any TIMESTAMP or DATETIME column in a table, you can assign the
current timestamp as the default value, the auto-update value, or
both:
An auto-initialized column is set to the current timestamp for inserted rows that specify no value for the column.
An auto-updated column is automatically updated to the current timestamp when the value of any other column in the row is changed
from its current value. An auto-updated column remains unchanged if
all other columns are set to their current values. To prevent an
auto-updated column from updating when other columns change,
explicitly set it to its current value. To update an auto-updated
column even when other columns do not change, explicitly set it to the
value it should have (for example, set it to CURRENT_TIMESTAMP).
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?
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.
I have a table called "users" and in that table there is a row for each account. In each row there is a column called "created" and in this I need to add the timestamp for when the account was created? So like when the user registers, the timestamp is automatically added. Also, when the values are updated in the row, I want the timestamp to stay the SAME. How can I accomplish this?
Create the table, and apply the default value for your created column.
CREATE TABLE IF NOT EXISTS `Users` (
`User_ID` int(11) NOT NULL,
... all other columns ...
`Created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
)
There is no need to update the Created (timestamp) when user update the info.
Just update the columns that need a change (e.g. email, address, etc)
using a trigger for the Created column is a bit overkill, I would say. It is better to use the default value instead. A Trigger in my opinion would be better for example a LastUpdated column. i.e. each time a user/account is modified it will update this column.
brief:
I'm experiencing strange MySQL behavior - on update CURRENT_TIMESTAMP attribute is being added although I don't want it to be added. I want to find out why is this happening - is it a matter of MySQL server or MySQL Workbench I'm using (v5.2.38).
detail:
I've modelled the database structure using EER diagrams, an example table is below:
CREATE TABLE IF NOT EXISTS `privilege` (
`id` INT NOT NULL ,
`name` VARCHAR(64) NOT NULL COMMENT 'privilege name (just a label)' ,
`created_at` TIMESTAMP NOT NULL COMMENT 'when the privilege was created' ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
The above script fragment is created using Export > Forward Engineer SQL Create Script inside WorkBench. The created_at column is siginifant here. It is NOT NULL and there is no default value defined for the timestamp when a record is defined. So I guess, that if someone tries to insert a record without defining created_at, an error will be raised.
I run this script inside MySQL server to create the whole structure. And the created structure is different - show create table privilege returns the following:
CREATE TABLE `privilege` (
`id` int(11) NOT NULL,
`name` varchar(64) NOT NULL COMMENT 'privilege name (just a label)',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP COMMENT 'when the privilege was created',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Where did "on update current_timestamp" come from? I'm 100% sure that I didn't choose any appropriate option, so MySQL should not create anything he's not asked to.
Does anyone have an idea why those clauses are added?
As documented under Automatic Initialization and Updating for TIMESTAMP:
The following rules describe the possibilities for defining the first TIMESTAMP column in a table with the current timestamp for both the default and auto-update values, for one but not the other, or for neither:
[ deletia ]
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.
[ deletia ]
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.