MySQL Case--Strict mode与NOT NULL

SQL Mode 与 NOT NULL

MySQL allows you to set different SQL MODE (GLOBAL or SESSION grade level) for compatibility with earlier versions of MySQL or compatible non-standard SQL, commonly used SQL MODE two are strict mode (strict mode) and a non-strict mode (non-strict mode), The difference was greater need to carefully set.

There follows a description of the SQL MODE and NOT NULL in MySQL official document:

Strict mode controls how MySQL handles invalid or missing values in data-change statements such as INSERT or UPDATE. A value can be invalid for several reasons. For example, it might have the wrong data type for the column, or it might be out of range. A value is missing when a new row to be inserted does not contain a value for a non-NULL column that has no explicit DEFAULT clause in its definition. (For a NULL column, NULL is inserted if the value is missing.) Strict mode also affects DDL statements such as CREATE TABLE.

Strict SQL mode applies to the following errors, represent a class of errors in which an input value is either invalid or missing. A value is invalid if it has the wrong data type for the column or might be out of range. A value is missing if a new row to be inserted does not contain a value for a NOT NULL column that has no explicit DEFAULT clause in its definition.

Changing a NULL column to NOT NULL in non-strict mode is prohibited to prevent converting NULL values to default non-NULL values, for which there are no corresponding values in the referenced table. The operation is permitted in strict mode, but an error is returned if any such conversion is required.

https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sql-mode-strict

 

Prepare the test environment

# Delete the existing table test 
drop the Table IF EXISTS tb1001; 

# create a test table 
the Create the Table tb1001 ( 
the above mentioned id int AUTO_INCREMENT Primary Key, 
c1 int 
); 

# insert test data 
INSERT INTO tb1001 (c1) the SELECT  1 ; 
INSERT INTO tb1001 (c1) the SELECT  2 ; 
INSERT INTO tb1001 (c1) the SELECT  3 ; 

# view the latest data 
the SELECT * from tb1001;
 + ---- + ------ + 
| the above mentioned id | c1 | 
+ ---- + ------ + 
|   1 |     1 | 
|   2 |    2 |
|  3 |    3 |
+----+------+

 

 NOT NULL restriction in strict mode

SESSION level set strict mode

set session sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

Test 1, no increase NOT NULL column with default values, the test passes, the existing records, will pay an initial value of the type (PS: timestamp column special, automatically generated default value, and there are differences in different versions)

alter table tb1001 
add c2 int not null,
add c3 varchar(10) not null,
add c4 datetime not null,
add c5 timestamp not null;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

select * from tb1001;
+----+------+----+----+---------------------+---------------------+
| id | c1   | c2 | c3 | c4                  | c5                  |
+----+------+----+----+---------------------+---------------------+
|  1 |    1 |  0 |    | 0000-00-00 00:00:00 | 2019-08-07 22:31:53 |
|  2 |    2 |  0 |    | 0000-00-00 00:00:00 | 2019-08-07 22:31:53 |
|  3 |    3 |  0 |    | 0000-00-00 00:00:00 | 2019-08-07 22:31:53 |
+----+------+----+----+---------------------+---------------------+
3 rows in set (0.00 sec)

 

Test 2, but does not insert the record explicitly set "NOT NULL and no default" value, the test fails column, under stringent mode, must be explicitly specified when inserting a column value "NOT NULL and no default value"

insert into tb1001(c1) select 4;
ERROR 1364 (HY000): Field 'c2' doesn't have a default value
insert into tb1001(c1,c2) select 4,4; ERROR 1364 (HY000): Field
'c3' doesn't have a default value
insert into tb1001(c1,c2,c3) select 4,4,4; ERROR 1364 (HY000): Field 'c4' doesn't have a default value
insert into tb1001(c1,c2,c3,c4) select 4,4,4,now(); Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0

 

Test 3, explicitly "NOT NULL and no default value" is recorded inserted column is set to NULL, the test fails, the strict mode is not the "NOT NULL and no default value" when a record columns explicitly assigned NULL

insert into tb1001(c1,c2,c3,c4) select 5,NULL,NULL,NULL;
ERROR 1048 (23000): Column 'c2' cannot be null


insert into tb1001(c1,c2,c3,c4) select 5,5,NULL,NULL;
ERROR 1048 (23000): Column 'c3' cannot be null


insert into tb1001(c1,c2,c3,c4) select 5,5,'5',NULL;
ERROR 1048 (23000): Column 'c4' cannot be null


insert into tb1001(c1,c2,c3,c4) select 5,5,'5',NOW();
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

 

Test 4, explicitly "NOT NULL and no default value" update records columns set to NULL, the test fails, the strict mode is not the "NOT NULL and no default value" update records listed explicitly assigned NULL.

UPDATE tb1001 SET C1=11, C2=NULL, C3=NULL, C4=NULL WHERE ID=1;
ERROR 1048 (23000): Column 'c2' cannot be null


UPDATE tb1001 SET C1=11, C2=11, C3=NULL, C4=NULL WHERE ID=1;
ERROR 1048 (23000): Column 'c3' cannot be null


UPDATE tb1001 SET C1=11, C2=11, C3='11', C4=NULL WHERE ID=1;
ERROR 1048 (23000): Column 'c4' cannot be null


UPDATE tb1001 SET C1=11, C2=11, C3='11', C4=NOW() WHERE ID=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

 

NOT NULL restriction under non-strict mode

Set the level of non-strict mode SESSION

set session sql_mode='ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

Test 1, no increase NOT NULL column with default values, the test passes, the existing records, will pay an initial value of the type (PS: timestamp column special, automatically generated default value, and there are differences in different versions)

alter table tb1001 
add c2 int not null,
add c3 varchar(10) not null,
add c4 datetime not null,
add c5 timestamp not null;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

select * from tb1001;
+----+------+----+----+---------------------+---------------------+
| id | c1   | c2 | c3 | c4                  | c5                  |
+----+------+----+----+---------------------+---------------------+
|  1 |    1 |  0 |    | 0000-00-00 00:00:00 | 2019-08-07 22:47:37 |
|  2 |    2 |  0 |    | 0000-00-00 00:00:00 | 2019-08-07 22:47:37 |
|  3 |    3 |  0 |    | 0000-00-00 00:00:00 | 2019-08-07 22:47:37 |
+----+------+----+----+---------------------+---------------------+
3 rows in set (0.00 sec)

Test 2, the insertion recording, but not explicitly set "NOT NULL and no default" value, the test through the column, in a non-strict mode, if "no default value NOT NULL and" right column during insertion is not specified explicitly the initial value of the value type is used.

insert into tb1001(c1) select 4;
Query OK, 1 row affected, 3 warnings (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 3


insert into tb1001(c1,c2) select 4,4;
Query OK, 1 row affected, 2 warnings (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 2


insert into tb1001(c1,c2,c3) select 4,4,4;
Query OK, 1 row affected, 1 warning (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 1


insert into tb1001(c1,c2,c3,c4) select 4,4,4,now();
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0


select * from tb1001 where c1=4;
+----+------+----+----+---------------------+---------------------+
| id | c1   | c2 | c3 | c4                  | c5                  |
+----+------+----+----+---------------------+---------------------+
|  4 |    4 |  0 |    | 0000-00-00 00:00:00 | 2019-08-07 22:50:01 |
|  5 |    4 |  4 |    | 0000-00-00 00:00:00 | 2019-08-07 22:50:01 |
|  6 |    4 |  4 | 4  | 0000-00-00 00:00:00 | 2019-08-07 22:50:01 |
|  7 |    4 |  4 | 4  | 2019-08-07 22:50:01 | 2019-08-07 22:50:01 |
+----+------+----+----+---------------------+---------------------+
4 rows in set (0.00 sec)

Column explicit assignment test 3, when a record explicitly "NOT NULL and no default value" column is set to NULL, the test passes, in a non-strict mode, when a record may be "NOT NULL and no default value" is NULL, the initial value will be the actual type of storage columns.

insert into tb1001(c1,c2,c3,c4) select 5,NULL,NULL,NULL;
Query OK, 1 row affected, 3 warnings (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 3


insert into tb1001(c1,c2,c3,c4) select 5,5,NULL,NULL;
Query OK, 1 row affected, 2 warnings (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 2


insert into tb1001(c1,c2,c3,c4) select 5,5,'5',NULL;
Query OK, 1 row affected, 1 warning (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 1


insert into tb1001(c1,c2,c3,c4) select 5,5,'5',NOW();
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0


select * from tb1001 where c1=5;
+----+------+----+----+---------------------+---------------------+
| id | c1   | c2 | c3 | c4                  | c5                  |
+----+------+----+----+---------------------+---------------------+
|  8 |    5 |  0 |    | 0000-00-00 00:00:00 | 2019-08-07 22:54:05 |
|  9 |    5 |  5 |    | 0000-00-00 00:00:00 | 2019-08-07 22:54:05 |
| 10 |    5 |  5 | 5  | 0000-00-00 00:00:00 | 2019-08-07 22:54:05 |
| 11 |    5 |  5 | 5  | 2019-08-07 22:54:05 | 2019-08-07 22:54:05 |
+----+------+----+----+---------------------+---------------------+
4 rows in set (0.00 sec)

Column explicit assignment test 4, update records explicitly "NOT NULL and no default value" column is set to NULL, the test fails, the non-strict model, update records may be "NOT NULL and no default value" is NULL, the initial value will be the actual type of storage columns.

UPDATE tb1001 SET C1=11, C2=11, C3='11', C4='1911-11-11 11:11:11' WHERE ID=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

## 更新前数据
select * from tb1001 where id=1;
+----+------+----+----+---------------------+---------------------+
| id | c1   | c2 | c3 | c4                  | c5                  |
+----+------+----+----+---------------------+---------------------+
|  1 |   11 | 11 | 11 | 1911-11-11 11:11:11 | 2019-08-07 22:58:49 |
+----+------+----+----+---------------------+---------------------+
1 row in set (0.00 sec)

UPDATE tb1001 SET C1=1, C2=NULL, C3=NULL, C4=NULL WHERE ID=1;
Query OK, 1 row affected, 3 warnings (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 3

## 更新后数据
select * from tb1001 where id=1;
+----+------+----+----+---------------------+---------------------+
| id | c1   | c2 | c3 | c4                  | c5                  |
+----+------+----+----+---------------------+---------------------+
|  1 |    1 |  0 |    | 0000-00-00 00:00:00 | 2019-08-07 22:59:34 |
+----+------+----+----+---------------------+---------------------+
1 row in set (0.00 sec)

 

to sum up

1, both in strict mode or non-strict mode, it allows the new column "NOT NULL and no default value" in the table have been recorded. 

2, in the strict mode is not allowed during insertion of "NOT NULL and no default value" column is not specified value or NULL value "NOT NULL and no default value" column of the update is not allowed to specify value NULL. 

3, in the non-strict mode, upon insertion of "the NOT NULL and no default value" not specified value or NULL value column, or update the specified NULL value column "the NOT NULL and no default value", will be NULL values to replace the initial value of the column type.

 

Guess you like

Origin www.cnblogs.com/gaogao67/p/11308109.html