10

I just discovered NOT NULL does not make a field required.

When creating a mysql table, how do I create a field that cannot contain null or blank (must have something in it)?

Léo Lam
  • 3,870
  • 4
  • 34
  • 44
Xi Vix
  • 1,381
  • 6
  • 24
  • 43
  • 2
    `NOT NULL` *does* make a field "required" in the sense that it needs to have a value stored. `NULL` means "no value". According to MySQL, a blank string is still a "value". I'd suggest having your client check if it's blank before inserting the data. – gen_Eric Jan 13 '15 at 16:32
  • This question might help: http://stackoverflow.com/q/24424363 – gen_Eric Jan 13 '15 at 16:34
  • you can add a `CHECK` constraint to disallow inserts or updates to "" or whatever other "semantic" null value. – MikeD Jan 13 '15 at 16:35
  • possible duplicate of [Mysql Column constraint as "not empty" / "required"](http://stackoverflow.com/questions/24424363/mysql-column-constraint-as-not-empty-required) – Mureinik Jan 13 '15 at 16:35
  • @MikeD: Problem is, in MySQL it doesn't actually *enforce* those. It'll parse it and add it, but it won't check it before an insert. Not quite sure why. – gen_Eric Jan 13 '15 at 16:35
  • 1
    Or see this http://stackoverflow.com/questions/2514178/im-looking-for-a-constraint-to-prevent-the-insert-of-an-empty-string-in-mysql – user4447899 Jan 13 '15 at 16:37
  • 1
    @RocketHazmat true ... just seen when following the links ... so use PRE-INSERT & PRE-UPDATE triggers ... one doesn't have to like those though – MikeD Jan 13 '15 at 16:38
  • NOT NULL won't work .. the reason I found out it doesn't work is I did an insert and did not provide anything for the field and it accepted emptiness. If MySQL would allow me to do this "NOT NULL DEFAULT NULL" then it would work because if I didn't provide a value for the field and it attempted to default it to NULL then it would error out. This to me is a MySQL oversight because the database designer should be able to say a field must contain a value forcing all future programmers to comply. Of course I know that I can force a value on the interface side or provide a default value. – Xi Vix Jan 13 '15 at 16:39
  • 1
    @XiVix: Remember, a blank string is considered a "value" by MySQL. – gen_Eric Jan 13 '15 at 16:42
  • I think you should do two things: Set the column to `NOT NULL` *and* create a trigger to check if the column is properly filled. See my answer below – Barranka Jan 13 '15 at 16:50

3 Answers3

5

By default, MySQL accepts invalid values. You can set MySQL to strict mode to force valid values. This will reject a query that does not provide a value for a NOT NULL column as well as enforce integrity on all types of columns.


Update: MySQL 5.7 and above now have strict mode on by default. So it would not accept invalid values by default like previous versions.


http://dev.mysql.com/doc/refman/5.0/en/sql-mode.html#sql-mode-important

http://dev.mysql.com/doc/refman/5.0/en/sql-mode.html#sqlmode_strict_all_tables

Edit: @Barranka and @RocketHazmat made good points in the comments. '' is not the same as null, so MySQL will allow that in a NOT NULL column. In that instance, you would have to resort to your code or a trigger.

In the code (PHP for example), this could be easy enough, running something like:

if (!strlen($value)) { 
    // Exclude value or use NULL in query
}
Devon Bessemer
  • 34,461
  • 9
  • 69
  • 95
  • can I do this just for a specific table or query or is it global? – Xi Vix Jan 13 '15 at 16:55
  • I'm not sure about per table. I know you can set it in the config file and you can set it in each session `SET sql_mode = ...;` – Devon Bessemer Jan 13 '15 at 16:57
  • I like to keep strict mode on in all of my databases, then program with that in mind. This makes sure that your program isn't inserting any invalid values as well. You set the parameters for the columns when creating the table, why not abide by them? – Devon Bessemer Jan 13 '15 at 16:59
1

I think you should do two things:

  1. Set the column to NOT NULL to force the input of a value
  2. Use a trigger to validate the values.

    Within the trigger you can cancel the operation if the desired column does not fulfill a required condition (for example, having zero-length).

This question and its answers address this second thing, and here is an example:

delimiter $$
CREATE TRIGGER `cancel_insert_if_empty`
BEFORE INSERT ON `your_table`
FOR EACH ROW
BEGIN
    declare msg varchar(255);
    if NEW.your_column is null or length(NEW.your_column) = 0 then
        set msg = "You're doing something wrong! Now suffer the consequences";
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
    end if;
END$$
delimiter ;

In this example, if you try to insert a null value or a zero-length string in your_column an error will rise and the insert will be canceled. Quoting from the reference manual:

MySQL handles errors during trigger execution as follows:

  • If a BEFORE trigger fails, the operation on the corresponding row is not performed.
  • A BEFORE trigger is activated by the attempt to insert or modify the row, regardless of whether the attempt subsequently succeeds.
  • An error during either a BEFORE or AFTER trigger results in failure of the entire statement that caused trigger invocation.

Of course, you can write a trigger to check the updates too.

Hope this helps.

Community
  • 1
  • 1
Barranka
  • 20,547
  • 13
  • 65
  • 83
  • thanks a bunch but I was trying to avoid using a trigger so I went with Devon and the strict approach. – Xi Vix Jan 13 '15 at 18:15
0

You can set default value for that field: City varchar(40) DEFAULT 'Sandnes'

Nikola
  • 131
  • 1
  • 6
  • 1
    This won't work if the user specifically inserts a zero-length string. Example: `insert into a_table(a_column) values('');` – Barranka Jan 13 '15 at 16:54
  • @Barranka, true. But technically that isn't null. So MySQL won't know the difference and then yes, you would need something like your answer. – Devon Bessemer Jan 13 '15 at 17:02