how to define null as integer value on mysql server? - mysql

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.

Related

distinguish in information_schema DB: column with default NULL vs. column with no DEFAULT

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

How to do unique constraint works with NULL value in MySQL

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

ERROR 1467 (HY000): Failed to read auto-increment value from storage engine

I am trying to import data from pipe delimited file to mysql. Creating the table works. However, when i try to import data i get this error "ERROR 1467 (HY000): Failed to read auto-increment value from storage engine".
I have checked on website for possible errors but any answers. Below is the script I am using. I am quite new to MySql.
SELECT 'Changing database..' as '';
use test
SELECT 'Droing table if it exists' as '';
DROP TABLE IF EXISTS table1;
CREATE TABLE IF NOT EXISTS table1
(
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
infohash VARCHAR(100) NOT NULL,
categories VARCHAR(100) DEFAULT NULL,
info_url VARCHAR(300) NOT NULL,
download_url VARCHAR(300) DEFAULT NULL,
PRIMARY KEY (id)
);
SHOW TABLES;
LOAD DATA INFILE '/usr/Software/sample.txt'
INTO TABLE table1
CHARACTER SET utf8
COLUMNS
TERMINATED BY '|'
LINES
TERMINATED BY '\n'
;
SELECT 'Total rows in table' as '';
select count(*) from table1;
Here is the output i am getting.
mysql> source table_creattion.sql
+---------------------+
| |
+---------------------+
| Changing database.. |
+---------------------+
1 row in set (0.00 sec)
Database changed
+---------------------------+
| |
+---------------------------+
| Droing table if it exists |
+---------------------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
+----------------+
| Tables_in_test |
+----------------+
| table1 |
+----------------+
1 row in set (0.00 sec)
ERROR 1467 (HY000): Failed to read auto-increment value from storage engine
+---------------------+
| |
+---------------------+
| Total rows in table |
+---------------------+
1 row in set (0.00 sec)
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
I am not sure why this error is coming. Anyone?
Try adding your fields name to insert statement as in the example below.
As I see it, on sample.txt, you don have to have a value for id column.
Please share some sample lines from sample.txt for better assiteance.
LOAD DATA INFILE '/usr/Software/sample.txt'
INTO TABLE table1
(infohash,categories, info_url, download_url )
CHARACTER SET utf8
COLUMNS
TERMINATED BY '|'
LINES
TERMINATED BY '\n'
;
The auto_increment column increase to its up limit 18446744073709551615.
This is a bug, when the user trys to insert a duplicate value on a uniqe key. My solution is, to insert a new dummy-record with defined ID (and the other required columns) and to delete it afterwards.
select max(`ID`) from `table1` into #IDmax;
set #IDmax = #IDmax + 1;
insert into `table1` set `ID` = #IDmax;
delete from `table1` where `ID` = #IDmax;

MySql silently ignores "references" keyword on table creation

mysql> create database test;
Query OK, 1 row affected (0.01 sec)
mysql> use test;
Database changed
mysql> create table one (id int not null primary key);
Query OK, 0 rows affected (0.03 sec)
mysql> -- here is the problem
mysql> create table two (oneid int not null references one(id));
Query OK, 0 rows affected (0.02 sec)
mysql> -- here are the first signs of issues!!!!
mysql> show create table two;
+-------+----------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------+
| two | CREATE TABLE `two` (
`oneid` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+----------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> -- here is the issue: an insert with no reference
mysql> insert into two values (-12);
Query OK, 1 row affected (0.01 sec)
mysql> select * from two;
+-------+
| oneid |
+-------+
| -12 |
+-------+
1 row in set (0.00 sec)
mysql> -- if you want to know:
mysql> SHOW Variables WHERE Variable_name='foreign_key_checks';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| foreign_key_checks | ON |
+--------------------+-------+
1 row in set (0.00 sec)
After my research, the only question here is: why MySql do not reject table two creation because of its not valid syntax and instead it silently create the table without the foreign key reference?
Just for completeness here is the correct syntax for MySql.
mysql> create table three(oneid int not null, CONSTRAINT whatEverName FOREIGN KEY (oneid) REFERENCES one(id));
Query OK, 0 rows affected (0.04 sec)
MySQL parses but ignores “inline REFERENCES specifications” (as defined in the SQL standard) where the references are defined as part of the column specification. MySQL accepts REFERENCES clauses only when specified as part of a separate FOREIGN KEY specification.
You can go here and read more yourself...

Create boolean column in MySQL with false as default value?

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.