14.24.3 表达式处理
使用精确数学,精确值数字将在可能时使用原样。例如,在比较中使用的数字将原样使用,不进行任何更改。在严格 SQL 模式下,对于INSERT
到具有精确数据类型(DECIMAL
或整数)的列中,数字将以其精确值被插入。如果严格 SQL 模式不启用,截断在INSERT
中是允许的。
处理数值表达式取决于表达式中包含的值类型:
如果数值表达式包含任何字符串,则将其转换为双精度浮点数值,并将表达式评估为近似值。
插入数值列受到 SQL 模式的影响,SQL 模式由sql_mode
系统变量控制。 (见第7.1.11节,“服务器 SQL 模式”。)以下讨论了严格模式(由STRICT_ALL_TABLES
或STRICT_TRANS_TABLES
模式值选择)和ERROR_FOR_DIVISION_BY_ZERO
。要启用所有限制,可以使用TRADITIONAL
模式,该模式包括严格模式值和ERROR_FOR_DIVISION_BY_ZERO
:
SET sql_mode='TRADITIONAL';
如果将数字插入到精确类型列 (DECIMAL
或整数) 中,它将以其精确值被插入,如果它在列范围和精度内。
如果值的分数部分有太多数字,会进行舍入,并生成一个注释。舍入是按照第14.24.4节,“舍入行为”中描述的方式进行的。舍入的分数部分的截断不是错误,即使在严格模式下。
如果值的整数部分有太多数字,它太大(超出范围)并被处理如下:
-
如果不启用严格模式,值将被截断到最近的合法值,并生成警告。
-
如果启用严格模式,会出现溢出错误。
下溢不检测,因此下溢处理是未定义的。
对于将字符串插入到数字列中,字符串到数字的转换如下,如果字符串包含非数字内容:
-
不能以非数字开头的字符串不能被用作数字,在严格模式下会产生错误,否则会生成警告。这包括空字符串。
-
以数字开头的字符串可以被转换,但是尾部非数字部分将被截断。如果截断部分包含除空格外的内容,这将在严格模式下产生错误,否则会生成警告。
默认情况下,除以零的结果是 NULL
,并无警告。通过设置 SQL 模式,可以限制除以零。
启用ERROR_FOR_DIVISION_BY_ZERO
SQL 模式,MySQL 处理除以零的方式:
-
如果不启用严格模式,会生成警告。
-
如果启用严格模式,插入和更新操作涉及除以零的表达式将被禁止,并出现错误。
换言之,涉及除以零的表达式的插入和更新操作可以被视为错误,但是这需要在严格模式下启用ERROR_FOR_DIVISION_BY_ZERO
。
假设我们有这个语句:
INSERT INTO t SET i = 1/0;
这是组合严格模式和ERROR_FOR_DIVISION_BY_ZERO
模式的结果。
sql_mode Value |
Result |
---|---|
'' (Default) |
无警告,无错误;i 设置为 NULL 。 |
strict | 无警告,无错误;i 设置为 NULL 。 |
ERROR_FOR_DIVISION_BY_ZERO |
警告,无错误;i 设置为 NULL 。 |
strict,ERROR_FOR_DIVISION_BY_ZERO |
错误条件;无行被插入。 |