mysql datetime default current timestamp - mysql

Recently i was exporting one of my database from localhost to a production environment and when i tried to plonk in the .sql file, the database that i was inporting the data into returned me an error on the datetime field which is DEFAULT CURRENT_TIMESTAMP. From what i read online, older sql phpadmin versions do not support datetime fields as default current timestamps but rather i must use timestamps.
However, thinking that my entire platform has been structured to suit datetime, is there anything i can do without needing to find a host that supports newer sql versions? Thanks!

Issue may be due to 'SQL_MODE' set to 'TRADITIONAL'.
Setting the SQL_MODE to either STRICT_TRANS_TABLES or ALLOW_INVALID_DATES would resolve the default values issue for datetime and timestamp type of columns.
Refer to MySQL Documentation:
Important SQL Modes
STRICT_TRANS_TABLES
TRADITIONAL
ALLOW_INVALID_DATES

Related

str_to_date not working on one database while working fine on another

I have 1 live database on a server (v5.5.58) and one local on my computer (v8.0.11) that is used as a testing database.
SELECT STR_TO_DATE("12:21:21", "%H:%i:%s")
Running this query on the server works fine while the same query locally returns date as null and a warning saying:
Warning: #1411 Incorrect datetime value: '12:21:21' for function str_to_date
I know that STR_TO_DATE works on MySql version 3.23 so it should work on version 8, right?
The ##SQL_MODE setting differs between your servers. Since 5.6, MySQL Server has used more strict default values for ##SQL_MODE.
If the NO_ZERO_DATE or NO_ZERO_IN_DATE SQL mode is enabled, zero dates or part of dates are disallowed. In that case, STR_TO_DATE() returns NULL and generates a warning
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_str-to-date
This same information appears in the documentation for previous versions.
You can often change newer servers to emulate the (usually permissive, sometimes wrong) behavior of older servers by changing the ##SQL_MODE to match, but do that with due discretion, since the more strict behavior is usually also more correct and helps avoid silent coercion of invalid values.

mysql - Need to allow '0000-00-00 00:00:00' dates

I want zero dates to be allowed in MySQL. I have changed the sql_mode to ALLOW_INVALID_DATES,NO_ENGINE_SUBSTITUTION.
I have changed it in /etc/mysql/my.cnf.
Yet, I when I try to insert data I get the error,
Data truncation: Incorrect datetime value: '0000-00-00 00:00:00'
The MySQL version is 5.7.18.
Any ideas on this would be of great help.
To allow zero dates (0000-00-00 00:00:00), you need to remove that restriction.
To remove particular SQL mode (in this case NO_ZERO_DATE), find the current SQL mode:
SELECT ##GLOBAL.sql_mode;
copy the result and remove from it what you don't need (NO_ZERO_DATE)
e.g.:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
to
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
create and open this file:
sudo vim /etc/mysql/conf.d/disable_strict_mode.cnf
and write and past into it your new SQL mode:
[mysqld]
sql-mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
restart MySQL:
sudo service mysql restart
I am going to assume here that you want to have a valid date so that your queries never have to check for NULL.
One way to do this, is to use what I like to call "In perpetuity" date(s).
These are essentially the min/max dates allowable for the DATETIME data type.
In my uses, there were typically "windows" of from - to pairs, but you might only need the minimum date.
From the Mysql manual:
The DATETIME type is used for values that contain both date and time
parts. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD
HH:MM:SS' format. The supported range is '1000-01-01 00:00:00' to
'9999-12-31 23:59:59'.
So one way that might work for you, is to utilize '1000-01-01 00:00:00' instead of the zero date.
You might want to read about other mode settings, such as strict and NO_ZERO_IN_DATE and NO_ZERO_DATE https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_zero_date
I could solve this by using zeroDateTimeBehavior=convertToNull
My solution when update table
SET sql_mode='';
UPDATE tnx_k2_items
SET created_by = 790
, modified = '0000-00-00 00:00:00'
, modified_by = 0
It should go without saying that you're doing it wrong. The column should be nullable if you intend to store nothing, and you shouldn't try to insert an empty string when you should be using a NULL.
Consider this, though:
If strict mode is not in effect, MySQL inserts adjusted values for invalid or missing values and produces warnings.
But when strict mode is in effect...
For transactional tables, an error occurs for invalid or missing values in a data-change statement when either STRICT_ALL_TABLES or STRICT_TRANS_TABLES is enabled. The statement is aborted and rolled back
http://dev.mysql.com/doc/refman/5.6/en/sql-mode.html#sql-mode-strict
SELECT ##SQL_MODE; should reveal that you are running with (at least) STRICT_TRANS_TABLES. While this isn't the internal default in 5.6, it is included in the default 5.6 configuration file. You'll want to remove it and restart the server if you want the old behavior.
...although you should consider making your code behave more correctly.
Try enabling this
ALLOW_INVALID_DATES
http://dev.mysql.com/doc/refman/5.6/en/sql-mode.html#sqlmode_allow_invalid_dates
Note: I do not recommend doing this. I'm just answering how to do it. In my opinion, it is better to clean up the queries and data, and provide a good default for columns that are non-null.

making mysql 5.7 behave like 5.1

I have migrated from a server running MySQL version 5.1.73 - Source Distribution to a server running 5.7.16-0ubuntu0.16.04.1 - (Ubuntu). Both servers are still up and running.
However, I'm encountering multiple (maddening) errors on queries that used to work, for example:
(Error #1364) Field 'Settings' doesn't have a default value
What is a fancy way of saying I didn't write the query on insert to include Settings because it didn't need a value yet.
So, I figure I'll go in and ALTER that field and give it a default value. MySQL lovingly tells me
#1101 - BLOB, TEXT, .. column 'Settings' can't have a default value
Thank you, MySQL..
So it looks like I'm going to have to refactor code, but this could take some time. What is the easiest way to make MySQL on the new server emulate 5.1.73?
UPDATE: It appears that one can make a LONGTEXT field be NULL (vs. NOT NULL), and then the default will in effect be null. But one cannot have a default that is "empty" or "blank" on a LONGTEXT or similar field. Lesson I'm learning here, be careful about making a skeleton/bare record entry into the db without referencing certain fields like this explicitly; any non-referenced LONGTEXT field will need to be null - which by the way is a reasonable and logical value vs. blank.
This has to do with the change they made in 5.7 to enforce strict SQL mode by default. The default SQL mode in MySQL 5.7 is: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION.
See http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-changes for more information.
You might ask, "why don't they make strict mode optional, but leave it off by default?" The answer is, they did—for about 10 years! It was time to make the next step and enforce strict mode by default. It helps bring MySQL into better SQL compliance and compatibility with other standard RDBMS products.
So how can you turn off strict mode to make it act like the previous, more lax SQL mode? It's easy, put this in your /etc/my.cnf:
sql_mode=NO_ENGINE_SUBSTITUTION
You can also enable that change without restarting mysqld:
mysql> SET GLOBAL sql_mode='NO_ENGINE_SUBSTITUTION';
You probably want to keep NO_ENGINE_SUBSTITUTION on. Engine substitution means for example if you declare a table with ENGINE=InnoDB but the InnoDB storage engine is not enabled for some reason, MySQL will create the table but make it MyISAM silently. This is a bad thing to let happen if you intended it to be InnoDB.

Date value in mysql tables changes while exporting mysql db

I am exporting mysql table to setup it on live, but while exporting DB I noticed that my date column value is changing.. If it was "2007-06-11 00:00:00" earlier then after export it is now changed to "2007-06-10 18:30:00",
why this is so?
anybody have idea about this?
Bug #13052 existed in versions of MySQL prior to 5.0.15, in which dump files expressed TIMESTAMP columns in the server's timezone but did not include a SET TIME_ZONE command to ensure anyone (or any subsequent server) reading the dump file understood that; without such a command, receiving servers assume that any TIMESTAMP values are in its default timezone.
Therefore a transfer between servers in timezones offset by 18:30 (e.g. from South Australia to California) would lead to the behaviour you observe.
Solutions to this problem, in some vague order of preference, include:
Upgrade the version of mysqldump on the original server to 5.0.15 or later (will result in the dumpfile expressing all TIMESTAMP values in UTC, with a suitable SET TIME_ZONE statement at the start);
Prior to export (or import), change the global time_zone variable on the source (or destination) server, so that it matches the setting on the other server at the time of import (or export):
SET GLOBAL time_zone = 'America/Los_Angeles'; -- ('Australia/Adelaide')
UPDATE the data after the fact, applying MySQL's CONVERT_TZ() function:
UPDATE my_table
SET my_column = CONVERT_TZ(
my_column,
'America/Los_Angeles',
'Australia/Adelaide'
);
If using either solution 2 or solution 3, beware to use the exact timezone of the relevant server's time_zone variable, in such a manner as to include any daylight savings time. However, note that as documented under MySQL Server Time Zone Support: "Named time zones can be used only if the time zone information tables in the mysql database have been created and populated." The article goes on to explain how to create and populate the time zone information tables.
before export database just follow below steps:
export with custom option
uncheck the checkbox below
Dump TIMESTAMP columns in UTC (enables TIMESTAMP columns to be dumped and reloaded between servers in different time zones)
show in below image

Why can't a text column have a default value in MySQL?

If you try to create a TEXT column on a table, and give it a default value in MySQL, you get an error (on Windows at least). I cannot see any reason why a text column should not have a default value. No explanation is given by the MySQL documentation. It seems illogical to me (and somewhat frustrating, as I want a default value!). Anybody know why this is not allowed?
Windows MySQL v5 throws an error but Linux and other versions only raise a warning. This needs to be fixed. WTF?
Also see an attempt to fix this as bug #19498 in the MySQL Bugtracker:
Bryce Nesbitt on April 4 2008 4:36pm:
On MS Windows the "no DEFAULT" rule is an error, while on other platforms it is often a warning. While not a bug, it's possible to get trapped by this if you write code on a lenient platform, and later run it on a strict platform:
Personally, I do view this as a bug. Searching for "BLOB/TEXT column can't have a default value" returns about 2,940 results on Google. Most of them are reports of incompatibilities when trying to install DB scripts that worked on one system but not others.
I am running into the same problem now on a webapp I'm modifying for one of my clients, originally deployed on Linux MySQL v5.0.83-log. I'm running Windows MySQL v5.1.41. Even trying to use the latest version of phpMyAdmin to extract the database, it doesn't report a default for the text column in question. Yet, when I try running an insert on Windows (that works fine on the Linux deployment) I receive an error of no default on ABC column. I try to recreate the table locally with the obvious default (based on a select of unique values for that column) and end up receiving the oh-so-useful BLOB/TEXT column can't have a default value.
Again, not maintaining basic compatability across platforms is unacceptable and is a bug.
How to disable strict mode in MySQL 5 (Windows):
Edit /my.ini and look for line
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Replace it with
sql_mode='MYSQL40'
Restart the MySQL service (assuming that it is mysql5)
net stop mysql5
net start mysql5
If you have root/admin access you might be able to execute
mysql_query("SET ##global.sql_mode='MYSQL40'");
Without any deep knowledge of the mySQL engine, I'd say this sounds like a memory saving strategy. I assume the reason is behind this paragraph from the docs:
Each BLOB or TEXT value is represented internally by a separately allocated object. This is in contrast to all other data types, for which storage is allocated once per column when the table is opened.
It seems like pre-filling these column types would lead to memory usage and performance penalties.
As the main question:
Anybody know why this is not allowed?
is still not answered, I did a quick search and found a relatively new addition from a MySQL developer at MySQL Bugs:
[17 Mar 2017 15:11] Ståle Deraas
Posted by developer:
This is indeed a valid feature request, and at first glance it might seem trivial to add. But TEXT/BLOBS values are not stored directly in the record buffer used for reading/updating tables. So it is a bit more complex to assign default values for them.
This is no definite answer, but at least a starting point for the why question.
In the mean time, I'll just code around it and either make the column nullable or explicitly assign a (default '') value for each insert from the application code...
"Support for DEFAULT in TEXT/BLOB columns"
is a
feature request in the MySQL Bugtracker (Bug #21532).
I see I'm not the only one who would like to put a default value in a TEXT column.
I think this feature should be supported in a later version of MySQL.
This can't be fixed in the version 5.0 of MySQL,
because apparently it would cause incompatibility and dataloss if anyone tried to transfer a database back and forth between the (current) databases that don't support that feature and any databases that did support that feature.
You can get the same effect as a default value by using a trigger
create table my_text
(
abc text
);
delimiter //
create trigger mytext_trigger before insert on my_text
for each row
begin
if (NEW.abc is null ) then
set NEW.abc = 'default text';
end if;
end
//
delimiter ;
Support for using expression as default values was added to MySQL 8.0.13, released 2018-10-22, and works for TEXT, JSON, BLOB and GEOMETRY.
You still cannot write :
create table foo(bar text default 'baz')
But you can now write:
create table foo(bar text default ('baz'))
Which achieve the same thing.
I normally run sites on Linux, but I also develop on a local Windows machine. I've run into this problem many times and just fixed the tables when I encountered the problems. I installed an app yesterday to help someone out and of course ran into the problem again. So, I decided it was time to figure out what was going on - and found this thread. I really don't like the idea of changing the sql_mode of the server to an earlier mode (by default), so I came up with a simple (me thinks) solution.
This solution would of course require developers to wrap their table creation scripts to compensate for the MySQL issue running on Windows. You'll see similar concepts in dump files. One BIG caveat is that this could/will cause problems if partitioning is used.
// Store the current sql_mode
mysql_query("set #orig_mode = ##global.sql_mode");
// Set sql_mode to one that won't trigger errors...
mysql_query('set ##global.sql_mode = "MYSQL40"');
/**
* Do table creations here...
*/
// Change it back to original sql_mode
mysql_query('set ##global.sql_mode = #orig_mode');
That's about it.
For Ubuntu 16.04:
How to disable strict mode in MySQL 5.7:
Edit file /etc/mysql/mysql.conf.d/mysqld.cnf
If below line exists in mysql.cnf
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Then Replace it with
sql_mode='MYSQL40'
Otherwise
Just add below line in mysqld.cnf
sql_mode='MYSQL40'
This resolved problem.
This is a very old question but still it doesn't seems to have been answered properly. And, my this answer isn't actual answer to the question - "WHY can't a text column have a default value", but as it isn't possible to write long text in comment, and as my comment could help someone to prevent the error, here it is as a separate answer:
Some are saying that the error is occurring because of OS - Windows-Linux; but this isn't directly related to OS. (However, there may be differences in default settings of MySQL within different installers for different OSes, I am not sure.)
The main reason is the flag STRICT_TRANS_TABLES for sql_mode setting. if a value is not specified in INSERT statement for TEXT datatype column and if the flag exist in the sql_mode setting then MySQL is reporting an error; and if the flag doesn't exist then MySQL is only reporting a warning and inserts the record.
So, to prevent this error, one can remove the STRICT_TRANS_TABLES from sql_mode setting of MySQL. (He my need to reset the mode to the previous value if it can affect other operations on the database.)
According to the documentation of SQL mode in MySQL ...
For STRICT_TRANS_TABLES, MySQL converts an invalid value to the closest valid value for the column and inserts the adjusted value. If a value is missing, MySQL inserts the implicit default value for the column data type. In either case, MySQL generates a warning rather than an error and continues processing the statement. Implicit defaults are described in Section 11.6, “Data Type Default Values”.
... and documentation of Data Type Default Values ...
The BLOB, TEXT, GEOMETRY, and JSON data types cannot be assigned a default value.
... TEXT column can not have a default value, but if STRICT_TRANS_TABLES is removed from sql_mode then MySQL inserts empty string '' if no value is specified for TEXT column in INSERT statement.