注:本文由大模型生成
在 MySQL 5.7 中,sql_mode
是一个系统变量,它用于控制 MySQL 服务器的 SQL 语法和数据验证。这个变量可以设置为一个或多个不同的模式值,每个值都会启用或禁用特定的 MySQL 功能或行为。
SQL Mode 的默认值
在 MySQL 5.7 的默认安装中,sql_mode
的默认值可能因不同的安装和配置而异。但通常,它可能包含以下一个或多个值:
STRICT_TRANS_TABLES
:对于事务表,启用严格模式。如果插入或更新的值不满足列的数据类型或约束(如 UNIQUE 或 FOREIGN KEY),则会产生错误而不是警告。NO_ZERO_IN_DATE
和NO_ZERO_DATE
:不允许日期和月份为零的日期(’0000-00-00’ 或 ‘2000-00-00’)。ERROR_FOR_DIVISION_BY_ZERO
:在除法运算中,如果除数为零,则产生错误而不是返回 NULL。NO_ENGINE_SUBSTITUTION
:如果请求的存储引擎不可用,则不使用替代引擎。
官网的链接如下:
如何查看和设置 SQL Mode
你可以使用以下 SQL 语句来查看当前的 sql_mode
值:
SELECT @@sql_mode;
要设置 sql_mode
的值,你可以使用 SET
语句:
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
注意,使用 GLOBAL
关键字会更改服务器的默认设置,影响新建立的连接。如果你只想更改当前会话的设置,可以省略 GLOBAL
关键字。但是,更改全局设置可能需要管理员权限,并且可能需要在 my.cnf
或 my.ini
配置文件中持久化。
配置文件中的 SQL Mode
在 MySQL 的配置文件(如 my.cnf
或 my.ini
)中,你可以使用 [mysqld]
部分来设置 sql_mode
:
[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
这样,每次服务器启动时都会使用这些设置。
常见的 SQL Mode 值
在 MySQL 5.7 中,sql_mode
是一组用于控制 SQL 语法和数据验证的规则。这些规则定义了 MySQL 如何处理某些边缘情况和不符合标准的行为。以下是对 MySQL 5.7 中 sql_mode
的主要参数值的详细说明:
ONLY_FULL_GROUP_BY
- 描述:对于使用 GROUP BY 的查询,如果 SELECT 列表中的列不是聚合函数的一部分,也不是 GROUP BY 子句的一部分,则会产生错误。
- 示例:如果查询
SELECT name, value FROM test GROUP BY name;
(且value
列未被聚合),在启用ONLY_FULL_GROUP_BY
时会报错。
STRICT_TRANS_TABLES
- 描述:对于事务表,启用严格模式。如果插入或更新的值不满足列的数据类型或约束(如 UNIQUE 或 FOREIGN KEY),则会产生错误而不是警告。
- 示例:尝试将一个非整数值插入到整数列中,在启用
STRICT_TRANS_TABLES
时会报错。
NO_ZERO_IN_DATE 和 NO_ZERO_DATE
- 描述:这两个模式共同防止使用无效日期,如包含零日期或月份的值。
- 示例:尝试插入日期 ‘0000-00-00’ 或 ‘2023-00-15’,在启用这些模式时会报错。
ERROR_FOR_DIVISION_BY_ZERO
- 描述:当尝试除以零时,产生错误而不是返回 NULL。
- 示例:查询
SELECT 1 / 0;
在启用此模式时会报错。
NO_ENGINE_SUBSTITUTION
- 描述:如果请求的存储引擎不可用,则不使用替代引擎,并产生错误。
- 示例:如果尝试使用未安装或禁用的存储引擎创建表,在启用此模式时会报错。
ALLOW_INVALID_DATES
- 描述:允许使用无效日期,只检查月份是否在 1-12 之间,日期是否在 1-31 之间,而不检查日期的实际有效性。
- 示例:插入日期 ‘2023-02-30’(2月没有30日)在启用此模式时不会报错。
ANSI_QUOTES
- 描述:允许使用双引号 (“ “) 作为识别符引号,而不是字符串引号。
- 示例:在启用此模式时,
SELECT "column_name" FROM table_name;
会将 “column_name” 视为列名,而不是字符串。
PIPES_AS_CONCAT
- 描述:将 ‘||’ 视为字符串连接操作符,而不是逻辑 OR 操作符。
- 示例:在启用此模式时,
SELECT 'Hello' || ' World';
将返回 ‘Hello World’。
NO_AUTO_CREATE_USER
- 描述:禁止 GRANT 语句自动创建用户。
- 示例:尝试使用 GRANT 语句创建一个新用户,在启用此模式时会报错。
NO_AUTO_VALUE_ON_ZERO
- 描述:当 AUTO_INCREMENT 列的值为 0 时,不会生成新的值。
- 示例:尝试将 AUTO_INCREMENT 列的值设置为 0,在启用此模式时不会生成新的自增值。
此外,还有其他一些 sql_mode
值,如 REAL_AS_FLOAT
、IGNORE_SPACE
、HIGH_NOT_PRECEDENCE
等,这些在特定场景下可能有用,但通常不如上述列出的常用。
如何设置:
你可以使用 SET
语句来设置 sql_mode
的值,例如:
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
或者,在 MySQL 的配置文件(如 my.cnf
或 my.ini
)中进行设置:
[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
请注意,更改配置文件后需要重启 MySQL 服务以使更改生效。