There's a log table with a TIMESTAMP column, that currently has precision down to the second.
This is not enough, cause sometimes multiple events happen in the same second, and this way we can't tell the order of the events happening.
I know this could be fixed with an automatically incremented ID (to put them in order of happening), but a Timestamp with millisecond precision is what I'm after since I would like to see how much time happens between two events.
If I change the columns default value from CURRENT_TIMESTAMP to CURRENT_TIMESTAMP(3), I get the following error in MySQL Workbench:
Executing:
ALTER TABLE `my_db`.`logs`
CHANGE COLUMN `timestamp` `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ;
Operation failed: There was an error while applying the SQL script to the database.
ERROR 1067: Invalid default value for 'timestamp'
SQL Statement:
ALTER TABLE `my_db`.`logs`
CHANGE COLUMN `timestamp` `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
I already have data in the table, which I wouldn't like to use, so I would like to alter this table.
Is it actually possible to alter the table this way, so from now on the timestamp column will be more precise?
PS:
I tried adding a new (totally blank) column with the added precision, but it threw the same error.
Your alter query has the (6) missing on a second spot:
ALTER TABLE `my_db`.`logs`
CHANGE COLUMN `timestamp` `timestamp` TIMESTAMP(6) NOT NULL DEFAULT
CURRENT_TIMESTAMP(6)
Related
I have this query
`ALTER TABLE `user_account_keys` CHANGE `DateTime` `DateTime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP`
It stops update_currnet_timestamp being enabled on a certain column. I need to disable it on every single column, in every single table, that comes under the type DateTime.
I'm not sure why MySQL has even enabled this without asking me.
You can set it to another default value since the column in NOT NULL. You can either allow nulls and then remove the default value or set it to another default value.
`ALTER TABLE `user_account_keys` CHANGE `DateTime` `DateTime` TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00'`
Change '2000-01-01 00:00:00' to whatever default value you need to use.
To change all the columns in the database, you can use something like this:
SELECT CONCAT('`ALTER TABLE `',TABLE_NAME,'` CHANGE `'
,COLUMN_NAME,'` `',COLUMN_NAME
,'` TIMESTAMP NOT NULL DEFAULT '
,'2000-01-01 00:00:00','`' ) ALTERTABLE
FROM information_schema.columns
WHERE data_type = 'timestamp';
This will give you a list of all the ALTER TABLE statements which you can verify before running using the EXEC command.
I have been making tables with a modified row which is time stamped.
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
I am seeking to rename this as bookedinand timestamp the day of entry into the database.
i have looked on the net for a solution at sites like http://www.w3schools.com/sql/func_curdate.asp
And cant seem to find a solution that works or is what i need.
I tried to edit it in the databse myself but with no luck. as you can tell im a extremity novice
Instead of w3schools you really should use the actual MySQL documentations. http://dev.mysql.com/doc/refman/5.1/en/alter-table.html
alter table tablename change `modified` `bookedin` timestamp NOT NULL DEFAULT
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
Or maybe just
alter table tablename change `modified` `bookedin` timestamp NOT NULL DEFAULT
CURRENT_TIMESTAMP;
I think the on update may just be part of the timestamp datatype. And, I think that altering the name of the table might cause all the rows to update their timestamp to the date you did it. So you might want to make a copy of the table and try it out first. I remember running into a problem like that once that made me switch from using TIMESTAMP to DATETIME.
I have the following schema with the following attributes:
USER(TABLE_NAME)
USER_ID|USERNAME|PASSWORD|TOPIC_NAME|FLAG1|FLAG2
I have 2 questions basically:
How can I make an attribute USER_ID as primary key and it should
automatically increment the value each time I insert the value into
the database.It shouldn't be under my control.
How can I retrieve a record from the database, based on the latest
time from which it was updated.( for example if I updated a record
at 2pm and same record at 3pm, if I retrieve now at 4pm I should get
the record that was updated at 3pm i.e. the latest updated one.)
Please help.
I'm assuming that question one is in the context of MYSQL. So, you can use the ALTER TABLE statement to mark a field as PRIMARY KEY, and to mark it AUTOINCREMENT
ALTER TABLE User
ADD PRIMARY KEY (USER_ID);
ALTER TABLE User
MODIFY COLUMN USER_ID INT(4) AUTO_INCREMENT; -- of course, set the type appropriately
For the second question I'm not sure I understand correctly so I'm just going to go ahead and give you some basic information before giving an answer that may confuse you.
When you update the same record multiple times, only the most recent update is persisted. Basically, once you update a record, it's previous values are not kept. So, if you update a record at 2pm, and then update the same record at 3pm - when you query for the record you will automatically receive the most recent values.
Now, if by updating you mean you would insert new values for the same USER_ID multiple times and want to retrieve the most recent, then you would need to use a field in the table to store a timestamp of when each record is created/updated. Then you can query for the most recent value based on the timestamp.
I assume you're talking about Oracle since you tagged it as Oracle. You also tagged the question as MySQL where the approach will be different.
You can make the USER_ID column a primary key
ALTER TABLE <<table_name>>
ADD CONSTRAINT pk_user_id PRIMARY KEY( user_id );
If you want the value to increment automatically, you'd need to create a sequence
CREATE SEQUENCE user_id_seq
START WITH 1
INCREMENT BY 1
CACHE 20;
and then create a trigger on the table that uses the sequence
CREATE OR REPLACE TRIGGER trg_assign_user_id
BEFORE INSERT ON <<table name>>
FOR EACH ROW
BEGIN
:new.user_id := user_id_seq.nextval;
END;
As for your second question, I'm not sure that I understand. If you update a row and then commit that change, all subsequent queries are going to read the updated data (barring exceptionally unlikely cases where you've set a serializable transaction isolation level and you've got transactions that run for multiple hours and you're running the query in that transaction). You don't need to do anything to see the current data.
(Answer based on MySQL; conceptually similar answer if using Oracle, but the SQL will probably be different.)
If USER_ID was not defined as a primary key or automatically incrementing at the time of table creation, then you can use:
ALTER TABLE tablename MODIFY USER_ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT;
To issue queries based on record dates, you have to have a field defined to hold date-related datetypes. The date and time of record modifications would be something you would manage (e.g. add/change) based on the way in which you are accessing the records (some PHP-related way? it's unclear what scripts you have in play, based on your question.) Once you have dates in your records you can ORDER BY the date field in your SELECT query.
Check this out
For your AUTOINCREMENT, Its a question already asked here
For your PRIMARY KEY use this
ALTER TABLE USER ADD PRIMARY KEY (USER_ID)
Can you provide more information. If the value gets updated you definitely do NOT have your old value that you entered at 2pm present in the dB. So querying for it will be fine
You can use something like this:
CREATE TABLE IF NOT EXISTS user (
USER_ID unsigned int(8) NOT NULL AUTO_INCREMENT,
username varchar(25) NOT NULL,
password varchar(25) NOT NULL,
topic_name varchar(100) NOT NULL,
flag1 smallint(1) NOT NULL DEFAULT 0,
flag2 smallint(1) NOT NULL DEFAULT 0,
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
For selection use query:
SELECT * from user ORDER BY update_time DESC
my simple question is .. Is it possible to insert php time() value by default in a column of a MYSQL database so that everytime i don't need to insert it. I know MYSQL provide CURR_TIMESTAMP..but they are not stored as integer unlike the time function which gives the timestamp as integer..
Any help will be greatly appreciated... Thanks
Example:
drop table if exists file_events;
create table file_events (
id int unsigned auto_increment not null,
file_id int unsigned not null,
event_time int unsigned not null default UNIX_TIMESTAMP(), # the field that defaults to "now"
primary key(id),
constraint foreign key fk_file_events_to_sam_files (file_id) references files(id) on delete cascade
) ENGINE=InnoDB;
If you want to do it on a mysql bases you can always use triggers [ http://dev.mysql.com/doc/refman/5.1/en/create-trigger.html ] just create a trigger to set the column of your choice to the current timestamp
You should just stick with the MySQL timestamp and convert it as needed. It is easy to do...
strtotime("put the mysql timestamp here");
will produce the same format (unix timestamp) as
time();
Unlike many other DBMS, MySQL doesn't support functions as default values. The only exception is the one you mention: dates accept CURRENT_TIMESTAMP (or one of their values). It appears to me that's quite an acceptable solution anyway since you can easily convert your Unix timestamp on-the-fly:
SELECT foo_id, foo_info
FROM foo
WHERE FROM_UNIXTIME(1294133369)<=foo_date
Or, from PHP:
$sql = "SELECT foo_id, foo_info
FROM foo
WHERE '" . date('Y-m-d H:i:s', 1294133369) . "')<=foo_date";
Whatever, if you absolutely need to store dates as integers, you must write your own triggers. Here's a nice example:
http://mysqldatabaseadministration.blogspot.com/2006/01/playing-with-triggers.html
This seems like a really simple one but I'm struggling to figure it out. I want a column in my database that lists when a record was first created and another column that says when it was updated. It's my understanding I should be able to do all this just using MySQL. All help is appreciated :)
This stinks still no answer, reasons I'm already starting to miss Ruby on Rails...
You will probably need to use a combination of the Datetime datatype and the Timestamp data type. I would set my created column as a DateTime with a DEFAULT NOW(), and my updated column as a Timestamp with DEFAULT CURRENT_TIMESTAMP and an ON UPDATE CURRENT_TIMESTAMP attribute.
Here are the docs for the Timestamp dt:
http://dev.mysql.com/doc/refman/5.0/en/timestamp.html
In a CREATE TABLE statement, the first TIMESTAMP column can be declared in any of the following ways:
With both DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses, the column has the current timestamp for its default value, and is automatically updated.
With neither DEFAULT nor ON UPDATE clauses, it is the same as DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.
With a DEFAULT CURRENT_TIMESTAMP clause and no ON UPDATE clause, the column has the current timestamp for its default value but is not automatically updated.
With no DEFAULT clause and with an ON UPDATE CURRENT_TIMESTAMP clause, the column has a default of 0 and is automatically updated.
With a constant DEFAULT value, the column has the given default and is not automatically initialized to the current timestamp. If the column also has an ON UPDATE CURRENT_TIMESTAMP clause, it is automatically updated; otherwise, it has a constant default and is not automatically updated.
To fulfill your question and for others viewing this question, here is the answer. Note this was written for MySQL 5.x.
DROP TABLE IF EXISTS `test1`;
CREATE TABLE `test1` (
`id` INT NULL AUTO_INCREMENT ,
`name` varchar(50) NOT NULL ,
`created` DATETIME ,
`updated` DATETIME ,
PRIMARY KEY (`id`),
INDEX (`name`)
);
DELIMITER $$
DROP TRIGGER IF EXISTS `test1_created`$$
CREATE TRIGGER `test1_created` BEFORE INSERT ON `test1`
FOR EACH ROW BEGIN
SET NEW.`created` = UTC_TIMESTAMP();
SET NEW.`updated` = UTC_TIMESTAMP();
END;
$$
DROP TRIGGER IF EXISTS `test1_updated`$$
CREATE TRIGGER `test1_updated` BEFORE UPDATE ON `test1`
FOR EACH ROW BEGIN
SET NEW.`updated` = UTC_TIMESTAMP();
END;
$$
DELIMITER ;
Note
You could use TIMESTAMP for the updated column which would have automatically updated the value thus not requiring the BEFORE UPDATE trigger, however TIMESTAMP has a range from 1970 to 2038 which is fast approaching and I like to think my applications will live forever :). Although TIMESTAMP is only 4bytes while DATETIME is 8bytes.
TIMESTAMP range '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC
DATETIME range '1000-01-01 00:00:00' to '9999-12-31 23:59:59'
From the MySQL 5.0 Certification Guide:
CREATE TABLE ts_test5 (
created TIMESTAMP DEFAULT 0,
updated TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
data CHAR(30)
);
To control the initialization and update behaviour of a TIMESTAMP column, you add either or both of the DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP attributes to the column defintion when creating the table with CREATE TABLE...
and
...if you do not specify either of the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes when creating a table, MySQL automatically assigns BOTH to the first TIMESTAMP column
Also
you cannot use DEFAULT CURRENT_TIMESTAMP with one column and ON UPDATE CURRENT_TIMESTAMP with another
If you can't use the timestamp fields with default attributes that Paul W has suggested, you can use AFTER INSERT and AFTER UPDATE triggers to populate the fields.
You will need two fields "Created" and
"Updated" with type datetime. When a
new entry is inserted then insert
"Created" with current time stamp.
When a update is happening insert
"Updated" with the current time stamp,
and let the "Created" field remain as
it is.
For current time stamp you can use
NOW() in your mysql query.