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

MysqlDefault Value

Mysql Problem Overview


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?

Mysql Solutions


Solution 1 - Mysql

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'");

Solution 2 - Mysql

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.

Solution 3 - Mysql

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...

Solution 4 - Mysql

"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.

Solution 5 - Mysql

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 ;

Solution 6 - Mysql

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.

Solution 7 - Mysql

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.

Solution 8 - Mysql

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.

Solution 9 - Mysql

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRussView Question on Stackoverflow
Solution 1 - MysqlKu LogixView Answer on Stackoverflow
Solution 2 - MysqlPekkaView Answer on Stackoverflow
Solution 3 - MysqlMarten KoetsierView Answer on Stackoverflow
Solution 4 - MysqlDavid CaryView Answer on Stackoverflow
Solution 5 - MysqlTim ChildView Answer on Stackoverflow
Solution 6 - MysqlDarrell GreenhouseView Answer on Stackoverflow
Solution 7 - MysqlShiv BuyyaView Answer on Stackoverflow
Solution 8 - MysqlOreilleView Answer on Stackoverflow
Solution 9 - MysqlNikunj BhattView Answer on Stackoverflow