I want to create a table in MySQL with a boolean column whose default value is false. But it's accepting NULL as default...
You have to specify 0 (meaning false) or 1 (meaning true) as the default. Here is an example:
create table mytable (
mybool boolean not null default 0
);
FYI: boolean is an alias for tinyint(1).
Here is the proof:
mysql> create table mytable (
-> mybool boolean not null default 0
-> );
Query OK, 0 rows affected (0.35 sec)
mysql> insert into mytable () values ();
Query OK, 1 row affected (0.00 sec)
mysql> select * from mytable;
+--------+
| mybool |
+--------+
| 0 |
+--------+
1 row in set (0.00 sec)
FYI: My test was done on the following version of MySQL:
mysql> select version();
+----------------+
| version() |
+----------------+
| 5.0.18-max-log |
+----------------+
1 row in set (0.00 sec)
You can set a default value at creation time like:
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
Married boolean DEFAULT false);
Use ENUM in MySQL for true / false it gives and accepts the true / false values without any extra code.
ALTER TABLE `itemcategory` ADD `aaa` ENUM('false', 'true') NOT NULL DEFAULT 'false'
If you are making the boolean column as not null then the default 'default' value is false; you don't have to explicitly specify it.
Related
i use mysql 5.7.
if i look only into 'information_schema' database, is there a way to distinguish a column with default NULL and a column without default?
here's my table:
mysql> CREATE TABLE defaults (default_null varchar(100) DEFAULT NULL, no_default varchar(100)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.02 sec)
mysql> ALTER TABLE defaults ALTER COLUMN no_default DROP DEFAULT;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW CREATE TABLE defaults;
+----------+------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+----------+------------------------------------------------------------------------------------------------------------------------------------------+
| defaults | CREATE TABLE `defaults` (
`default_null` varchar(100) DEFAULT NULL,
`no_default` varchar(100)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+----------+------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> INSERT INTO defaults SET no_default = 'foo';
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO defaults SET default_null = 'bar';
ERROR 1364 (HY000): Field 'no_default' doesn't have a default value
mysql>
no_default and default_null columns are different, but in information_schema.columns table they are the same:
mysql> SELECT column_name, is_nullable, IFNULL(column_default, 'real NULL') FROM information_schema.columns WHERE table_name = 'defaults';
+--------------+-------------+-------------------------------------+
| column_name | is_nullable | IFNULL(column_default, 'real NULL') |
+--------------+-------------+-------------------------------------+
| default_null | YES | real NULL |
| no_default | YES | real NULL |
+--------------+-------------+-------------------------------------+
2 rows in set (0.01 sec)
mysql>
This behaviour has every Version if strict sql mode is enabled.
If strict SQL mode is enabled, an INSERT statement generates an error if it does not specify an explicit value for every column that has no default value. See Section 5.1.10, “Server SQL Modes”.
You can find it under https://dev.mysql.com/doc/refman/5.7/en/insert.html
I am looking for how to implement unique constraints with NULL check.
MySQL shouldn't allow multiple null value.
Employee:
id | name
---|-----
1 | null
2 | null -> should give error during inserting 2nd row.
No, MySQL is doing the right thing, according to the SQL-99 specification.
https://mariadb.com/kb/en/sql-99/constraint_type-unique-constraint/
A UNIQUE Constraint makes it impossible to COMMIT any operation that
would cause the unique key to contain any non-null duplicate values.
(Multiple null values are allowed, since the null value is never equal
to anything, even another null value.)
If you use a UNIQUE constraint but don't want multiple rows with NULL, declare the columns as NOT NULL and prohibit any row from having NULL.
MySQL 5.7 does allow for a workaround:
mysql> CREATE TABLE `null_test` (
-> `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
-> `const` varchar(255) NOT NULL DEFAULT '',
-> `deleted_at` datetime DEFAULT NULL,
-> PRIMARY KEY (`id`)
-> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.03 sec)
With soft deletes, it would be nice if you could have just one row with a with a deleted_at = NULL per constraint.
mysql> ALTER TABLE `null_test` ADD `vconst` int(1) GENERATED ALWAYS AS (((NULL = `deleted_at`) or (NULL <=> `deleted_at`))) VIRTUAL;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
So I created a virtual column that will flip from 1 to null when deleted_at gets set.
mysql> ALTER TABLE `null_test` ADD UNIQUE KEY `nullable_index` (`const`,`vconst`);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
Instead of including deleted_at to the unique constraint add the virtual column, vconst.
mysql> INSERT INTO `null_test` SET `const` = 'Ghost';
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM `null_test` WHERE `const` = 'Ghost';
+--------+-------+------------+--------+
| id | const | deleted_at | vconst |
+--------+-------+------------+--------+
| 999901 | Ghost | NULL | 1 |
+--------+-------+------------+--------+
1 row in set (0.01 sec)
No need to insert the vconst (but you cannot, anyhow).
mysql> INSERT INTO `null_test` SET `const` = 'Ghost';
ERROR 1062 (23000): Duplicate entry 'Ghost-1' for key 'nullable_index'
Inserting it again throws the Duplicate entry error.
mysql> UPDATE `null_test` SET `deleted_at` = NOW() WHERE `const` = 'Ghost';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
Same with setting delete_at, no need to touch vconst, it will flip automatically.
mysql> SELECT * FROM `null_test` WHERE `const` = 'Ghost';
+--------+-------+---------------------+--------+
| id | const | deleted_at | vconst |
+--------+-------+---------------------+--------+
| 999901 | Ghost | 2017-02-16 22:07:45 | NULL |
+--------+-------+---------------------+--------+
1 row in set (0.00 sec)
mysql> INSERT INTO `null_test` SET `const` = 'Ghost';
Query OK, 1 row affected (0.00 sec)
Now you are free to insert a new row with the same constraints!
mysql> SELECT * FROM `null_test` WHERE `const` = 'Ghost';
+--------+-------+---------------------+--------+
| id | const | deleted_at | vconst |
+--------+-------+---------------------+--------+
| 999901 | Ghost | 2017-02-16 22:07:45 | NULL |
| 999903 | Ghost | NULL | 1 |
+--------+-------+---------------------+--------+
2 rows in set (0.01 sec)
In this case, depending on how much you soft delete, setting deleted_at, you might want to include deleted_at to the index, or a new index with it, but I will let my load tests decide.
alter table yourtable add column `virtual_null` varchar(20) GENERATED ALWAYS AS (if(isnull(`your_nullable_column`),'null',`your_nullable_column`))) VIRTUAL;
alter table yourtable add constraint unique(virtual_null);
Make this and be happy, behind the scenes mysql's null is a hash value. Because that its impossible compare two null values...
Sorry by poor english, good luck
I am trying to figure out if is possible to set an Integer, auto increment as primary key, could start with 0? like 01, 02,0234324 ?
Is it possible??
Should a numeric ID , that is also a primary key have that format? Dont know if possible, but in case it is, would it be a good practice?
Thanks
In MySQL an auto-increment field has to be an integer. For an integer there is no difference between 02 and 2 as far as storage is concerned. However, you can change the default display using the ZEROFILL attribute like this:
> create table t1 (n int(11) zerofill not null auto_increment primary key);
Query OK, 0 rows affected (0.07 sec)
> insert into t1 values (null);
Query OK, 1 row affected (0.02 sec)
> select * from t1;
+-------------+
| n |
+-------------+
| 00000000001 |
+-------------+
1 row in set (0.03 sec)
I have the payouts table to whom I set the default as 0.000 for my total_tips column (extract from my table schema):
total_tips | decimal(12, 4) | YES | | 0.0000 | <- Default set as '0.0000'
But now, can anyone explain why I have still NULL values inside my table:
mysql> select total_tips from payouts where id = 4157;
+------------+
| total_tips |
+------------+
| NULL |
+------------+
1 row in set (0.00 sec)
Before that I ran a ALTER command which look like this (to set the default value):
mysql> ALTER TABLE payouts change total_tips total_tips decimal(12,4) default 0 ;
You maybe didn't set the value as NOT NULL, so the NULL value is accepted. You need to update your whole base with:
UPDATE payouts SET total_tips = 0 WHERE total_tips IS NULL
if you set defaults on existing columns in tables which already stores data then the existing rows are not automatically updated.
i mean this is only true for mssql and mysql. in oracle existing lines WILL BE updated.
I need to allow saving null as integer value on mysql server, how can I do this?
Assuming your question is about the "Incorrect integer value" error message...
mysql> CREATE TABLE `foo` (
-> `foo_id` INT(10) NOT NULL AUTO_INCREMENT,
-> `foo_size` INT(10) NOT NULL DEFAULT '0',
-> PRIMARY KEY (`foo_id`)
-> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO foo (foo_size) VALUES ('');
ERROR 1366 (HY000): Incorrect integer value: '' for column 'foo_size' at row 1
... that means that your server is running in strict mode (which is actually good). You can disable it:
mysql> SET ##session.sql_mode='';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO foo (foo_size) VALUES ('');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+---------+------+------------------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------------------+
| Warning | 1366 | Incorrect integer value: '' for column 'foo_size' at row 1 |
+---------+------+------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM foo;
+--------+----------+
| foo_id | foo_size |
+--------+----------+
| 1 | 0 |
+--------+----------+
1 row in set (0.00 sec)
... and your error will be downgraded to warning.
I found out how:
I hided the line below then restarted the sql server and it worked.
# Set the SQL mode to strict
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Note this line is found in my.ini file.
Set the field to not null and set its default to zero:
CREATE TABLE `t` (
`foo` BIGINT NOT NULL DEFAULT 0
);
Value of foo will be zero if you send it NULL.