Databases 13 min read

Understanding MySQL SQL_MODE: Values, Settings, and Migration Practices

This article explains MySQL's SQL_MODE system variable, its default values for different versions, common configuration options, how it influences data validation and migration, and provides practical code examples for adjusting and testing SQL_MODE settings.

Aikesheng Open Source Community
Aikesheng Open Source Community
Aikesheng Open Source Community
Understanding MySQL SQL_MODE: Values, Settings, and Migration Practices

The article, authored by Xu Xiang of the iKang MySQL DBA team, introduces SQL_MODE , a MySQL system variable that controls how SQL statements are parsed, validated, and executed, ensuring data accuracy, completeness, and consistency.

SQL_MODE can enforce strict data checks, enforce standard‑compliant SQL syntax, and facilitate smoother data migration between heterogeneous databases.

The guide covers three main knowledge points: the default SQL_MODE values for different MySQL versions, the meaning of commonly used SQL_MODE options, and the critical role of SQL_MODE during data migration.

MySQL 5.7 default SQL_MODE includes the following options:

ONLY_FULL_GROUP_BY

STRICT_TRANS_TABLES

NO_ZERO_DATE

NO_ZERO_IN_DATE

ERROR_FOR_DIVISION_BY_ZERO

NO_AUTO_CREATE_USER

NO_ENGINE_SUBSTITUTION

-- MySQL 5.7
mysql> show variables like 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                                                       |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode      | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

MySQL 8.0 default SQL_MODE is similar but omits NO_AUTO_CREATE_USER:

-- MySQL 8.0
mysql> show variables like 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                                                       |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode      | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION               |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

Common configuration modes include:

ANSI : relaxed mode that allows invalid dates but stores them as 0000-00-00 with a warning.

STRICT_TRANS_TABLES : strict mode that rejects invalid data with an error (applies to transactional tables).

STRICT_ALL_TABLES : strict mode for all tables.

TRADITIONAL : strict mode that also rolls back the transaction on error.

An example demonstrates how an illegal date '2007-04-31' behaves under different modes:

mysql> select @@session.sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@session.sql_mode                                                                                                                            |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> set session sql_mode='ANSI';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> create table t_sql_mode_ansi(d datetime);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t_sql_mode_ansi values('2007-04-31');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from t_sql_mode_ansi;
+---------------------+
| d                   |
+---------------------+
| 0000-00-00 00:00:00 |
+---------------------+
1 row in set (0.00 sec)

mysql> set session sql_mode='TRADITIONAL';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> insert into t_sql_mode_ansi values('2007-04-31');
ERROR 1292 (22007): Incorrect datetime value: '2007-04-31' for column 'd' at row 1

The results show that the ANSI mode converts the illegal date to 0000-00-00 with a warning, while TRADITIONAL (and other strict modes) reject the insert outright.

SQL_MODE in migration

When migrating MySQL databases to other systems, adjusting SQL_MODE helps reduce compatibility issues. Recommended pre‑migration steps include disabling strict modes (e.g., STRICT_TRANS_TABLES ), disabling ONLY_FULL_GROUP_BY , and enabling a more relaxed mode to identify problematic data.

SET GLOBAL SQL_MODE='';

Additional adjustments such as disabling NO_ENGINE_SUBSTITUTION or enabling NO_TABLE_OPTIONS can simplify the generation of portable CREATE TABLE statements.

mysql> show create table test\G
*************************** 1. row ***************************
        Table: test
Create Table: CREATE TABLE `test` (
  `ename` varchar(10) COLLATE utf8mb4_bin DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sal` decimal(10,2) DEFAULT NULL,
  `hiredate` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
1 row in set (0.00 sec)

mysql> set session sql_mode='NO_TABLE_OPTIONS';
Query OK, 0 rows affected, 2 warnings (0.00 sec)

mysql> show create table test\G
*************************** 1. row ***************************
        Table: test
Create Table: CREATE TABLE `test` (
  `ename` varchar(10) COLLATE utf8mb4_bin DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sal` decimal(10,2) DEFAULT NULL,
  `hiredate` date DEFAULT NULL
)
1 row in set (0.00 sec)

During migration, attention should be paid to date/time handling, empty‑string vs. NULL semantics, and identifier case sensitivity. After migration, comprehensive compatibility testing should verify query results, data integrity, and performance, as some SQL_MODE settings can affect query speed.

Conclusion

Strict SQL_MODE settings such as TRADITIONAL and STRICT_TRANS_TABLES provide strong data validation, while flexible combinations of modes allow tailoring to application needs, especially when migrating data to other database platforms.

MySQLdatabase migrationdata validationsql_modeSQL Settings
Aikesheng Open Source Community
Written by

Aikesheng Open Source Community

The Aikesheng Open Source Community provides stable, enterprise‑grade MySQL open‑source tools and services, releases a premium open‑source component each year (1024), and continuously operates and maintains them.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.