表达式处理
对于精确数学,将尽可能使用给出的精确值数字。例如,比较中的数字将完全按照给定的方式使用,而不会更改值。在严格的SQL模式下,对于INSERT
具有精确数据类型(DECIMAL
或整数)的列,如果数字在列范围内,则以其精确值插入数字。检索时,该值应与插入的值相同。(如果未启用严格的SQL模式,则允许截断为INSERT
。)
数值表达式的处理取决于该表达式包含哪种类型的值:
- 如果存在任何近似值,则该表达式为近似值,并使用浮点算法对其求值。
- 如果没有近似值,则表达式仅包含精确值。如果任何精确值包含小数部分(小数点后的值),则使用
DECIMAL
精确算术对表达式求值,并且精度为65位数。术语“精确”受可以用二进制表示的限制。例如,1.0/3.0
可以用十进制表示法近似为.333...
,但不能写为确切的数字,因此(1.0/3.0)*3.0
不求和为1.0
。 - 否则,表达式仅包含整数值。该表达式是精确的,并且使用整数算术求值,并且精度与
BIGINT
(64位)相同。
如果数字表达式包含任何字符串,则将它们转换为双精度浮点值,并且该表达式为近似值。
插入数字列受SQL模式的影响,该模式由sql_mode
系统变量控制。(请参见“服务器SQL模式”。)以下讨论提到了严格模式(由STRICT_ALL_TABLES
or STRICT_TRANS_TABLES
模式值选择)和ERROR_FOR_DIVISION_BY_ZERO
。要打开所有限制,您可以简单地使用TRADITIONAL
mode,它包括严格的模式值和ERROR_FOR_DIVISION_BY_ZERO
:
SET sql_mode='TRADITIONAL';
如果将数字插入精确类型列(DECIMAL
或整数),则在列范围和精度范围内,将以其精确值插入数字。
如果该值的小数位数过多,则会四舍五入并生成一个音符。如“舍入行为”中所述进行舍入。即使在严格模式下,由于小数部分舍入而导致的截断也不是错误。
如果该值在整数部分中包含太多数字,则它太大(超出范围),并按以下方式处理:
- 如果未启用严格模式,则该值将被截断为最接近的合法值并生成警告。
- 如果启用严格模式,则会发生溢出错误。
未检测到下溢,因此未定义下溢处理。
对于将字符串插入数字列,如果字符串具有非数字内容,则按以下方式处理从字符串到数字的转换:
- 不以数字开头的字符串不能用作数字,并且在严格模式下会产生错误,否则会发出警告。这包括空字符串。
- 可以转换以数字开头的字符串,但尾随的非数字部分将被截断。如果截断的部分包含空格以外的其他内容,则会在严格模式下产生错误,否则会发出警告。
默认情况下,被零除会产生结果,NULL
并且没有警告。通过适当设置SQL模式,可以限制除以零。
随着ERROR_FOR_DIVISION_BY_ZERO
启用SQL模式,MySQL的零处理师是不同的:
- 如果未启用严格模式,则会发生警告。
- 如果启用了严格模式,则禁止插入和除以零的更新,并且会发生错误。
换句话说,涉及执行零除表达式的插入和更新可被视为错误,但这ERROR_FOR_DIVISION_BY_ZERO
除了严格模式外还需要。
假设我们有以下语句:
INSERT INTO tSET i = 1/0;
这就是严格和ERROR_FOR_DIVISION_BY_ZERO
模式的结合。
sql_mode 值 | 结果 |
---|---|
'' (默认) | 没有警告,没有错误;i 设置为NULL 。 |
严格 | 没有警告,没有错误;i 设置为NULL 。 |
ERROR_FOR_DIVISION_BY_ZERO | 警告,没有错误;i 设置为NULL 。 |
严格,ERROR_FOR_DIVISION_BY_ZERO | 错误条件;没有插入行。 |