Setting a column as timestamp in MySql workbench? - mysql

This might be a really elementary question, but I've never created a table with TIMESTAMP() before, and I'm confused on what to put as the parameters. For example, here:
I just randomly put TIMESTAMP(20), but what does the 20 as a parameter signify here? What should be put in here?
I googled the question, but didn't really come up with anything so... Anyway I'm new to sql, so any help would be greatly appreciated, thank you!!

EDIT
As of MySQL 5.6.4, datatype TIMESTAMP(n) specifies n (0 up to 6) decimal digits of precision for fractional seconds.
Before MySQL 5.6, MySQL did not support fractional seconds stored as part of a TIMESTAMP datatype.
Reference: https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html
We don't need to specify a length modifier on a TIMESTAMP. We can just specify TIMESTAMP by itself.
But be aware that the first TIMESTAMP column defined in the table is subject to automatic initialization and update. For example:
create table foo (id int, ts timestamp, val varchar(2));
show create table foo;
CREATE TABLE `foo` (
`id` INT(11) DEFAULT NULL,
`ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`val` VARCHAR(2) DEFAULT NULL
)
What goes in parens following a datatype depends on what the datatype is, but for some datatypes, it's a length modifier.
For some datatypes, the length modifier affects the maximum length of values that can be stored. For example, VARCHAR(20) allows up to 20 characters to be stored. And DECIMAL(10,6) allows for numeric values with four digits before the decimal point and six after, and effective range of -9999.999999 to 9999.999999.
For other types, the length modifier it doesn't affect the range of values that can be stored. For example, INT(4) and INT(10) are both integer, and both can store the full range of values for allowed for the integer datatype.
What that length modifier does in that case is just informational. It essentially specifies a recommended display width. A client can make use of that to determine how much space to reserve on a row for displaying values from the column. A client doesn't have to do that, but that information is available.
EDIT
A length modifier is no longer accepted for the TIMESTAMP datatype. (If you are running a really old version of MySQL and it's accepted, it will be ignored.)

Thats the precision my friend, if you put for example (2) as a parameter, you will get a date with a precision like: 2015-12-29 00:00:00.00, by the way the maximum value is 6.

This syntax seems to be from old version of MySQL, prior to 4.1. It has been removed completely from 5.5 https://dev.mysql.com/doc/refman/5.0/en/upgrading-from-previous-series.html
So no point in specifying a width here, as it may be ignored. What version are you running?

MySQL 5.7 appears to support this syntax. The argument passed is the precision. TIMESTAMP(3) will allow millisecond precision. 6 is the highest amount of allowed precision.
reference: http://dev.mysql.com/doc/refman/5.7/en/datetime.html

In MySQL workbench 8.0
TIMESTAMP
doesn't work, you need to add wole statement (if u don't want to update timestamp in future)
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
than u have e.g :
2020-01-08 19:10:05
but if you want that TIMESTAMP could be modify with the record update than you use :
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

Related

How to store unix timestamp as int with default and on update?

I have been updating my MySQL tables with the following:
ALTER TABLE logs ADD COLUMN updateTimeStamp timestamp DEFAULT current_timestamp() ON UPDATE current_timestamp;
This stores the timestamp in the format of
2021-12-29 15:21:34
I tried originally to do the alter like so:
ALTER TABLE logs ADD COLUMN updateTimeStamp timestamp DEFAULT unix_timestamp() ON UPDATE unix_timestamp();
so that could store like 12121232, however that results in an error.
Is there anyway I can achieve the default and on update and store the timestamp in the format of 1212112, instead of the human readable datetime?
I know I can do SELECT unix_timestamt(columnname), but ideally I don't want to do that.
If you want to automatically get an integer when you select the column, you need to make it an int (or int unsigned) type. You can set its default with default (unix_timestamp()) (the extra parentheses are needed when not using one of the historically allowed default values). And you will need to add a trigger to set it on update.
But I suggest you not do that; just use a timestamp type. You just make future trouble for yourself by not using the type designed to store timestamps.

UUID as default for MySQL id column

I am trying to add a column to an existing table in MySql 8.0.17. The column needs to contain a UUID and I am trying to set it as a default value.
This is the statement I am executing
ALTER TABLE myTable ADD COLUMN UUID varchar(36) NOT NULL DEFAULT (UUID());
However I am getting the following error
Error Code: 1674. Statement is unsafe because it uses a system function that may return a different value on the slave.
I have read from other posts that it is possible to create a Trigger on the table however i would like to find out whether it is possible to set it directly as the default value on the column.
Also, what would be the advantage of using a binary conversion of the UUID over just a simple UUID ?
Eg.
ALTER TABLE myTable ADD COLUMN UUID binary(16) NOT NULL DEFAULT (UUID_TO_BIN(UUID(), true));
Thanks for your help.
assigning UUID() as DEFAULT value won't work, because It does not guarantee that the same value will be generated on your replica. That is why using TRIGGER is good option for new records (insertions).
If your intention is to update current records as well, you can write an update statement
update myTable
set UUID = UUID()
your column is of type binary(16) which means UUID data is implicitly converted to binary. using UUID_TO_BIN is not needed.
EDIT:
CHAR/VARCHAR is the human-readable format. whereas, binary is the compact format.
That means compressing the 32 characters (36 or more with separators) to the 16-bit format or back to the human-readable format.
If you dont mind about reading UUID, best is to use binary format
Change VARCHAR to CHAR, this will let you use 16bit.
Old Method
ALTER TABLE myTable ADD COLUMN UUID varchar(36) NOT NULL DEFAULT (UUID());
New Method
ALTER TABLE myTable ADD COLUMN UUID BINARY(36) NOT NULL DEFAULT (UUID_TO_BIN(UUID()));

mariadb/mysql - How to make a date column with sysdate/curdate?

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

Convert default column value from datetime to varchar

I have to add a varchar column to a table which defaults to the current timestamp. To do this I somehow need to convert the value from datetime to varchar.
I tried the following
ALTER TABLE `TableName`
CHANGE COLUMN `DocumentID` `DocumentID` VARCHAR(150) NULL DEFAULT CONVERT(NOW(), CHAR);
or
ALTER TABLE `TableName`
CHANGE COLUMN `DocumentID` `DocumentID` VARCHAR(150) NULL DEFAULT CONVERT(CURRENT_TIMESTAMP, CHAR);
I always get an error message, that my syntax is wrong. I am using MariaDB and HeidiSQL. Is there a way to do this?
EDIT: I am basically looking for a MySQL equivalent of the following SQL Server statement:
ALTER TABLE [dbo].[TableName] ADD CONSTRAINT [DF_TableName_DocumentID] DEFAULT (getdate()) FOR [DocumentID]
MariaDB document says
In MariaDB 10.2.1 you can use most functions in DEFAULT. Expressions
should have parentheses around them.
Hence you may check for the version of MariaDB and use the right syntax (parenthesis around expression):
(CONVERT(CURRENT_TIMESTAMP, CHAR))
Update
As an alternative, you may use Trigger to set the function value for the stable releases (< 10.2)
If you use CURRENT_TIMESTAMP as default value, you must use the datatype that the function retrieves, in this case is a timestamp as you can see in the docs.
I don't know the reasons that may lead you to save this as a varchar. I'm not sure but I think that MariaDB doesn't allow to call functions as default values so you can't convert CURRENT_TIMESTAMP as varchar. You have an alternative approach, make an after insert trigger updating the field (you can call CONVERT(CURRENT_TIMESTAMP, VARCHAR) inside a trigger).
Either way, I recomend to stay with timestamp.
I see the field is called "DocumentID", perhaps you want to save a hash value as identifier? You can archieve this with virtual columns. An example.

Issue inserting timestamp value in MySQL

There are some other questions where people have problems with timestamp being all zeros. I have checked them and this is not a duplicate.
I declare a table like this:
CREATE TABLE `my_db`.`my_table` (
`time_stamp` timestamp NOT NULL,
`author` varchar() NOT NULL,
`text` text NOT NULL,
`md5` int(11) NOT NULL,
PRIMARY KEY (`time_stamp`)
) ;
I also have a second table which will have a timestamp as primary key and they should have the same value.
Coding in Delphi, I use SELECT CURRENT_TIMESTAMP which returns something like '19/6/2010 4:56:17 AM' which I then use in an INSERT statement. The INSERT succeeds, but the timestamp is all zeros.
What am I doing wrong?
Here's the INSERT code:
sqlCommand := 'INSERT INTO my_db.my_table(time_stamp, author, text, md5) VALUES ("'
+ timestamp +
'", "mawg", ' +
'"Hello, world"' +
0 +
'");';
Result := DoSQlCommandWithNoResultSet(sqlCommand, AdoConnection);
Insertion will be extremely low rate, one entry every few weeks or maybe months, so I am happy with timestamp as primary key. I am keeping "versions" of things, so timestamp makes sense to me.
I am begging to think that this is an ADO problem, although I would expect ADO to just "pass through". I don't see any other solution. In a console, the output is "correct", but when run through ADO in Delphi then it is wrong
Can I specify to MySQL how it ought to format its dates?
After reviewing the MySQL documentation, it appears that if your timestamp value is incorrectly formatted, it would normally cause the timestamp to be '0000-00-00 00:00:00'.
In any case, you don't need to specify a timestamp value—that's the benefit of TIMESTAMP over DATETIME. And even if you did, you can simply set it to NOW() instead of running an unnecessary SELECT statement.
Edit:
Also, I know you said you thought this through, but have you considered daylight savings time? This could cause two records to have the same timestamp when the clock is set back during autumn.
Edit 2:
K, I don't know why I didn't catch this earlier, but that timestamp format you gave is incorrect. Try inserting a valid timestamp like '2010/06/19 4:56:17'. MySQL has pretty relaxed parsing of date & time values, but it always has to be year-month-date and hour-minute-seconds.
Edit 3:
Alright, there seems to be a little confusion over this, so I'm gonna post this quote from the MySQL 5.0 doc page on the DATETIME format:
For values specified as strings that include date part delimiters, it is not necessary to specify two digits for month or day values that are less than 10. '1979-6-9' is the same as '1979-06-09'. Similarly, for values specified as strings that include time part delimiters, it is not necessary to specify two digits for hour, minute, or second values that are less than 10. '1979-10-30 1:2:3' is the same as '1979-10-30 01:02:03'.
Have a look at MySQL date functions. They are very extensive and allow a high flexibility.
Besides all that, I would recommend re-thinking your table structure. A timestap as a primary key is not exactly what you want. When you have high traffic, it CAN happen, that the timestamp is the same. Also if you are saving 2 or more records in a row, the timestamp will be the same. Furthermore, your MD5 column is set to int(11). MD5 hashes use mixed characters, so i would rather go with varchar(32).
CREATE TABLE `my_db`.`my_table` (
`id` int(11) NOT NULL,
`timestamp` timestamp NOT NULL,
`author` varchar(100) NOT NULL,
`text` text NOT NULL,
`md5` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ;
AFAIR 19/6/2010 4:56:17 AM is not a valid date format for MySQL date types. You should convert it to 2010-06-19 04:56:14 (see doc).