12.3 Type Conversion in Expression Evaluation表达式求值中的类型转换

When an operator is used with operands of different types, type conversion occurs to make the operands compatible. 当运算符与不同类型的操作数一起使用时,会进行类型转换以使操作数兼容。Some conversions occur implicitly. 有些转换是隐式进行的。For example, MySQL automatically converts strings to numbers as necessary, and vice versa.例如,MySQL会根据需要自动将字符串转换为数字,反之亦然。

mysql> SELECT 1+'1';
        -> 2
mysql> SELECT CONCAT(2,' test');
        -> '2 test'

It is also possible to convert a number to a string explicitly using the CAST() function. 也可以使用CAST()函数显式地将数字转换为字符串。Conversion occurs implicitly with the CONCAT() function because it expects string arguments.CONCAT()函数会隐式进行转换,因为它需要字符串参数。

mysql> SELECT 38.8, CAST(38.8 AS CHAR);
        -> 38.8, '38.8'
mysql> SELECT 38.8, CONCAT(38.8);
        -> 38.8, '38.8'

See later in this section for information about the character set of implicit number-to-string conversions, and for modified rules that apply to CREATE TABLE ... SELECT statements.有关隐式数字到字符串转换的字符集的信息,以及适用于CREATE TABLE ... SELECT语句的修改规则,请参阅本节后面的内容。

The following rules describe how conversion occurs for comparison operations:以下规则描述了比较操作的转换方式:

For information about conversion of values from one temporal type to another, see Section 11.2.7, “Conversion Between Date and Time Types”.有关将值从一种时间类型转换为另一种时间类型的信息,请参阅第11.2.7节,“日期和时间类型之间的转换”

Comparison of JSON values takes place at two levels. JSON值的比较在两个级别上进行。The first level of comparison is based on the JSON types of the compared values. 第一级比较基于比较值的JSON类型。If the types differ, the comparison result is determined solely by which type has higher precedence. 如果类型不同,则比较结果仅取决于哪个类型具有更高的优先级。If the two values have the same JSON type, a second level of comparison occurs using type-specific rules. 如果这两个值具有相同的JSON类型,则使用特定于类型的规则进行第二级比较。For comparison of JSON and non-JSON values, the non-JSON value is converted to JSON and the values compared as JSON values. 为了比较JSON和非JSON值,将非JSON值转换为JSON,并将值作为JSON值进行比较。For details, see Comparison and Ordering of JSON Values.有关详细信息,请参阅JSON值的比较和排序

The following examples illustrate conversion of strings to numbers for comparison operations:以下示例说明了将字符串转换为数字以进行比较操作:

mysql> SELECT 1 > '6x';
        -> 0
mysql> SELECT 7 > '6x';
        -> 1
mysql> SELECT 0 > 'x6';
        -> 0
mysql> SELECT 0 = 'x6';
        -> 1

For comparisons of a string column with a number, MySQL cannot use an index on the column to look up the value quickly. 对于字符串列与数字的比较,MySQL不能使用该列上的索引来快速查找值。If str_col is an indexed string column, the index cannot be used when performing the lookup in the following statement:如果str_col是索引字符串列,则在以下语句中执行查找时不能使用索引:

SELECT * FROM tbl_name WHERE str_col=1;

The reason for this is that there are many different strings that may convert to the value 1, such as '1', ' 1', or '1a'.原因是有许多不同的字符串可以转换为值1,例如'1'' 1''1a'

Comparisons between floating-point numbers and large values of INTEGER type are approximate because the integer is converted to double-precision floating point before comparison, which is not capable of representing all 64-bit integers exactly. 浮点数和整数类型的大值之间的比较是近似的,因为在比较之前整数被转换为双精度浮点,这不能准确地表示所有64位整数。For example, the integer value 253 + 1 is not representable as a float, and is rounded to 253 or 253 + 2 before a float comparison, depending on the platform.例如,整数值253+1不能表示为浮点数,在进行浮点数比较之前,根据平台将其舍入为253或253+2。

To illustrate, only the first of the following comparisons compares equal values, but both comparisons return true (1):举例来说,以下比较中只有第一个比较的值相等,但两个比较都返回true1):

mysql> SELECT '9223372036854775807' = 9223372036854775807;
        -> 1
mysql> SELECT '9223372036854775807' = 9223372036854775806;
        -> 1

When conversions from string to floating-point and from integer to floating-point occur, they do not necessarily occur the same way. 当从字符串到浮点以及从整数到浮点的转换发生时,它们不一定以相同的方式发生。The integer may be converted to floating-point by the CPU, whereas the string is converted digit by digit in an operation that involves floating-point multiplications. 整数可以由CPU转换为浮点,而字符串则在涉及浮点乘法的操作中逐位转换。Also, results can be affected by factors such as computer architecture or the compiler version or optimization level. 此外,结果还可能受到计算机体系结构、编译器版本或优化级别等因素的影响。One way to avoid such problems is to use CAST() so that a value is not converted implicitly to a float-point number:避免此类问题的一种方法是使用CAST(),以便值不会隐式转换为浮点数:

mysql> SELECT CAST('9223372036854775807' AS UNSIGNED) = 9223372036854775806;
        -> 0

For more information about floating-point comparisons, see Section B.3.4.8, “Problems with Floating-Point Values”.有关浮点比较的更多信息,请参阅第B.3.4.8节“浮点值问题”

The server includes dtoa, a conversion library that provides the basis for improved conversion between string or DECIMAL values and approximate-value (FLOAT/DOUBLE) numbers:服务器包括dtoa,这是一个转换库,为改进字符串或DECIMAL值与近似值(FLOAT/DOUBLE)之间的转换提供了基础:

Because the conversions produced by this library differ in some cases from non-dtoa results, the potential exists for incompatibilities in applications that rely on previous results. 由于此库生成的转换在某些情况下与非dtoa结果不同,因此依赖于以前结果的应用程序中存在不兼容的可能性。For example, applications that depend on a specific exact result from previous conversions might need adjustment to accommodate additional precision.例如,依赖于以前转换的特定精确结果的应用程序可能需要调整以适应额外的精度。

The dtoa library provides conversions with the following properties. dtoa库提供具有以下属性的转换。D represents a value with a DECIMAL or string representation, and F represents a floating-point number in native binary (IEEE) format.D表示以DECIMAL或字符串表示的值,F表示本机二进制(IEEE)格式的浮点数。

These properties imply that F -> D -> F conversions are lossless unless F is -inf, +inf, or NaN. 这些性质意味着F -> D -> F转换是无损的,除非F-inf+infNaNThe latter values are not supported because the SQL standard defines them as invalid values for FLOAT or DOUBLE.后面的那些值不受支持,因为SQL标准将它们定义为FLOATDOUBLE的无效值。

For D -> F -> D conversions, a sufficient condition for losslessness is that D uses 15 or fewer digits of precision, is not a denormal value, -inf, +inf, or NaN. 对于D -> F -> D转换,无损性的一个充分条件是D使用15位或更少的精度,不是一个非规范值、-inf+inf,或NaNIn some cases, the conversion is lossless even if D has more than 15 digits of precision, but this is not always the case.在某些情况下,即使D的精度超过15位,转换也是无损的,但情况并非总是如此。

Implicit conversion of a numeric or temporal value to string produces a value that has a character set and collation determined by the character_set_connection and collation_connection system variables. 将数值或时态值隐式转换为字符串将生成一个值,该值具有由character_set_connection系统变量和collation_connection系统变量确定的字符集和排序规则。(These variables commonly are set with SET NAMES. (这些变量通常用SET NAMES设置。For information about connection character sets, see Section 10.4, “Connection Character Sets and Collations”.)有关连接字符集的信息,请参阅第10.4节,“连接字符集和排序规则”。)

This means that such a conversion results in a character (nonbinary) string (a CHAR, VARCHAR, or LONGTEXT value), except in the case that the connection character set is set to binary. 这意味着这种转换会产生字符(非二进制)字符串(CHARVARCHARLONGTEXT值),除非连接字符集设置为二进制。In that case, the conversion result is a binary string (a BINARY, VARBINARY, or LONGBLOB value).在这种情况下,转换结果是一个二进制字符串(BINARYVARBINARYLONGBLOB值)。

For integer expressions, the preceding remarks about expression evaluation apply somewhat differently for expression assignment; for example, in a statement such as this:对于整数表达式,前面关于表达式求值的注释对表达式赋值的应用略有不同;例如,在这样的语句中:

CREATE TABLE t SELECT integer_expr;

In this case, the table in the column resulting from the expression has type INT or BIGINT depending on the length of the integer expression. 在本例中,表达式产生的列中的表的类型为INTBIGINT,具体取决于整数表达式的长度。If the maximum length of the expression does not fit in an INT, BIGINT is used instead. 如果表达式的最大长度不适合INT,则改用BIGINTThe length is taken from the max_length value of the SELECT result set metadata (see C API Basic Data Structures). 长度取自SELECT结果集元数据的max_length值(请参阅C API基本数据结构)。This means that you can force a BIGINT rather than INT by use of a sufficiently long expression:这意味着您可以使用足够长的表达式强制使用BIGINT而不是INT

CREATE TABLE t SELECT 000000000000000000000;