Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  Functions and Operators  /  Cast Functions and Operators

14.10 转换函数和运算符

表 14.15 转换函数和运算符

Name Description Deprecated
BINARY 将字符串转换为二进制字符串
CAST() 将值转换为某种类型
CONVERT() 将值转换为某种类型

转换函数和运算符使得可以将值从一个数据类型转换到另一个数据类型。

  • BINARY expr

    BINARY 运算符将表达式转换为二进制字符串(一个具有 binary 字符集和 binary 排序规则的字符串)。BINARY 的常见用途是强制字符字符串比较以字节为单位,而不是以字符为单位。同时,BINARY 还会使尾部空格在比较中变得重要。关于 binary 字符集的排序规则和非二进制字符集的 _bin 排序规则之间的差异,见第12.8.5节,“The binary Collation Compared to _bin Collations”

    BINARY 运算符已弃用;您应该预期在 MySQL 的未来版本中删除它。请使用 CAST(... AS BINARY) 而不是。

    mysql> SET NAMES utf8mb4 COLLATE utf8mb4_general_ci;
            -> OK
    mysql> SELECT 'a' = 'A';
            -> 1
    mysql> SELECT BINARY 'a' = 'A';
            -> 0
    mysql> SELECT 'a' = 'a ';
            -> 1
    mysql> SELECT BINARY 'a' = 'a ';
            -> 0

    BINARY 在比较操作中影响整个操作;它可以在两个操作数前面使用,结果相同。

    将字符串表达式转换为二进制字符串,这些构造是等价的:

    CONVERT(expr USING BINARY)
    CAST(expr AS BINARY)
    BINARY expr

    如果值是一个字符串字面量,可以不进行转换地将其指定为二进制字符串,使用 _binary 字符集引导符:

    mysql> SELECT 'a' = 'A';
            -> 1
    mysql> SELECT _binary 'a' = 'A';
            -> 0

    关于引导符的信息,请参见第12.3.8节,“字符集引导符”

    BINARY 表达式操作符在表达式中与字符列定义中的BINARY 属性不同。对于以BINARY 属性定义的字符列,MySQL 将分配表默认字符集和该字符集的二进制(_bin)排序规则。每个非二进制字符集都有一个_bin 排序规则。例如,如果表默认字符集是 utf8mb4,以下两个列定义是等价的:

    CHAR(10) BINARY
    CHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin

    CHARVARCHARTEXT 列定义中使用CHARACTER SET binary,导致该列被视为相应的二进制字符串数据类型。例如,以下两个定义对应:

    CHAR(10) CHARACTER SET binary
    BINARY(10)
    
    VARCHAR(10) CHARACTER SET binary
    VARBINARY(10)
    
    TEXT CHARACTER SET binary
    BLOB

    如果从BINARYmysql客户端中调用,二进制字符串将以十六进制表示,取决于--binary-as-hex的值。关于该选项的更多信息,请参见第6.5.1节,“mysql — MySQL 命令行客户端”.

  • CAST(expr AS type [ARRAY])

    CAST(timestamp_value AT TIME ZONE timezone_specifier AS DATETIME[(precision)])

    timezone_specifier: [INTERVAL] '+00:00' | 'UTC'

    使用CAST(expr AS type 语法,CAST() 函数将任何类型的表达式转换为指定类型的结果值。这一操作也可以用CONVERT(expr, type) 表达式来表示,两者等价。如果exprNULLCAST() 返回 NULL

    这些type 值是允许的:

    • BINARY[(N)]

      生成一个字符串,类型为 VARBINARY,除非表达式 expr 是空(零长度),结果类型为 BINARY(0)。如果可选的长度 N 给出,BINARY(N) 使得转换使用不超过 N 字节的参数。值短于 N 字节则以 0x00 字节填充到长度为 N。如果可选的长度 N 不给出,MySQL 从表达式中计算最大长度。如果供给或计算的长度超过内部阈值,结果类型为 BLOB。如果长度仍然太长,结果类型为 LONGBLOB

      关于将到 BINARY 的转换如何影响比较,请参见第13.3.3节,“BINARY 和 VARBINARY 类型”

    • CHAR[(N)] [charset_info]

      生成一个字符串,除非表达式 expr为空(零长度),否则结果类型为 CHAR(0)。如果可选的长度 N 给出,CHAR(N) 使得转换使用不超过 N 个字符的参数。对于长度小于 N 的值,不进行填充。如果可选的长度 N 不给出,MySQL 从表达式中计算最大长度。如果提供或计算的长度超过内部阈值,结果类型为 TEXT。如果长度仍然太长,结果类型为 LONGTEXT

      没有 charset_info 子句,CHAR 生成一个默认字符集的字符串。要指定字符集,可以使用以下这些 charset_info 值:

      • CHARACTER SET charset_name:生成一个给定字符集的字符串。

      • ASCIICHARACTER SET latin1 的简写形式。

      • UNICODECHARACTER SET ucs2 的简写形式。

      在所有情况下,字符串都具有字符集的默认排序规则。

    • DATE

      生成一个DATE值。

    • DATETIME[(M)]

      生成一个DATETIME值。如果可选的M值被给出,它指定小数点后的精度。

    • DECIMAL[(M[,D])]

      生成一个DECIMAL值。如果可选的MD值被给出,它们指定最大数字(精度)和小数点后的数字(比例)。如果D被省略,0被假定。如果M被省略,10被假定。

    • DOUBLE

      生成一个DOUBLE结果。

    • FLOAT[(p)]

      如果不指定精度p,结果类型为FLOAT。如果提供了p,且0 <= p <= 24,则结果类型为FLOAT。如果25 <= p <= 53,则结果类型为DOUBLE。如果p < 0 或 p > 53,则返回错误。

    • JSON

      生成一个JSON值。关于JSON和其他类型之间的转换规则,见JSON值的比较和排序

    • NCHAR[(N)]

      类似于CHAR第12.3.7节,“国家字符集”

      CHAR不同,NCHAR不允许指定尾部字符集信息。

    • REAL

      产生类型为REAL的结果。如果启用了REAL_AS_FLOAT SQL 模式,那么实际上是FLOAT;否则结果为类型DOUBLE

    • SIGNED [INTEGER]

      产生一个有符号BIGINT值。

    • spatial_type

      CAST()CONVERT() 支持将几何值从一个空间类型转换到另一个空间类型,适用于某些空间类型的组合。详细信息请见空间类型的转换操作

    • TIME[(M)]

      产生一个TIME值。如果给定可选的M值,它指定了小数点秒精度。

    • UNSIGNED [INTEGER]

      产生一个无符号BIGINT值。

    • YEAR

      产生一个YEAR值。这些规则 governs 将其转换为 YEAR 的方式如下:

      • 对于范围在1901-2155之间的四位数字,或者可以解释为四位数字的字符串,返回相应的 YEAR 值。

      • 对于一位或两位数字,或者可以解释为这样一个数字的字符串,返回一个 YEAR 值:

        • 如果数字在1-69之间,添加2000并返回和。

        • 如果数字在70-99之间,添加1900并返回和。

      • 对于评估为0的字符串,返回2000。

      • 对于数字0,返回0。

      • 对于DATEDATETIMETIMESTAMP值,返回该值的 YEAR 部分。对于TIME值,返回当前年份。

        如果不指定 TIME 参数的类型,你可能会得到你期望以外的结果,如下所示:

        mysql> SELECT CAST("11:35:00" AS YEAR), CAST(TIME "11:35:00" AS YEAR);
        +--------------------------+-------------------------------+
        | CAST("11:35:00" AS YEAR) | CAST(TIME "11:35:00" AS YEAR) |
        +--------------------------+-------------------------------+
        |                     2011 |                          2021 |
        +--------------------------+-------------------------------+
      • 如果参数是类型DECIMALDOUBLEDECIMALREAL,则将该值四舍五入到最接近的整数,然后尝试将该值转换为YEAR,使用整数值的规则,如下所示:

        mysql> SELECT CAST(1944.35 AS YEAR), CAST(1944.50 AS YEAR);
        +-----------------------+-----------------------+
        | CAST(1944.35 AS YEAR) | CAST(1944.50 AS YEAR) |
        +-----------------------+-----------------------+
        |                  1944 |                  1945 |
        +-----------------------+-----------------------+
        
        mysql> SELECT CAST(66.35 AS YEAR), CAST(66.50 AS YEAR);
        +---------------------+---------------------+
        | CAST(66.35 AS YEAR) | CAST(66.50 AS YEAR) |
        +---------------------+---------------------+
        |                2066 |                2067 |
        +---------------------+---------------------+
      • 类型GEOMETRY的参数不能转换为YEAR

      • 无法成功转换到YEAR的值返回NULL

      包含非数字字符的字符串值在转换前必须被截断,会引发警告,如下所示:

      mysql> SELECT CAST("1979aaa" AS YEAR);
      +-------------------------+
      | CAST("1979aaa" AS YEAR) |
      +-------------------------+
      |                    1979 |
      +-------------------------+
      1 row in set, 1 warning (0.00 sec)
      
      mysql> SHOW WARNINGS;
      +---------+------+-------------------------------------------+
      | Level   | Code | Message                                   |
      +---------+------+-------------------------------------------+
      | Warning | 1292 | Truncated incorrect YEAR value: '1979aaa' |
      +---------+------+-------------------------------------------+

    InnoDB 允许在JSON 数组作为CREATE INDEXCREATE TABLEALTER TABLE 语句中使用额外的ARRAY 关键字。除非在这些语句中用于创建多值索引,否则不支持。ARRAY所指的列必须是类型为JSON 的列。使用ARRAY时,type 关键字后可以指定CAST() 支持的任何类型,除了BINARYJSONYEAR。语法信息、示例和其他相关信息,请参见多值索引

    Note

    CONVERT(),不同于CAST(),不支持多值索引创建或ARRAY 关键字。

    CAST() 支持将 TIMESTAMP 值作为 UTC 时间,使用 AT TIME ZONE 操作符。唯一支持的时区是 UTC,可以指定为 '+00:00''UTC'。该语法中唯一支持的返回类型是 DATETIME,且可选的精度指定在 0 到 6 之间,包括。

    TIMESTAMP 值使用时区偏移也被支持。

    mysql> SELECT @@system_time_zone;
    +--------------------+
    | @@system_time_zone |
    +--------------------+
    | EDT                |
    +--------------------+
    1 row in set (0.00 sec)
    
    mysql> CREATE TABLE tz (c TIMESTAMP);
    Query OK, 0 rows affected (0.41 sec)
    
    mysql> INSERT INTO tz VALUES
        ->     ROW(CURRENT_TIMESTAMP),
        ->     ROW('2020-07-28 14:50:15+1:00');
    Query OK, 1 row affected (0.08 sec)
    
    mysql> TABLE tz;
    +---------------------+
    | c                   |
    +---------------------+
    | 2020-07-28 09:22:41 |
    | 2020-07-28 09:50:15 |
    +---------------------+
    2 rows in set (0.00 sec)
    
    mysql> SELECT CAST(c AT TIME ZONE '+00:00' AS DATETIME) AS u FROM tz;
    +---------------------+
    | u                   |
    +---------------------+
    | 2020-07-28 13:22:41 |
    | 2020-07-28 13:50:15 |
    +---------------------+
    2 rows in set (0.00 sec)
    
    mysql> SELECT CAST(c AT TIME ZONE 'UTC' AS DATETIME(2)) AS u FROM tz;
    +------------------------+
    | u                      |
    +------------------------+
    | 2020-07-28 13:22:41.00 |
    | 2020-07-28 13:50:15.00 |
    +------------------------+
    2 rows in set (0.00 sec)

    如果您使用 'UTC' 作为时间 zone 指定符号,并且服务器抛出错误,如Unknown or incorrect time zone: 'UTC',可能需要安装 MySQL 时区表(见Populating the Time Zone Tables)。

    AT TIME ZONE 不支持 ARRAY 关键字,并且不被CONVERT() 函数支持。

  • CONVERT(expr USING transcoding_name)

    CONVERT(expr,type)

    CONVERT(expr USING transcoding_name) 是标准SQL语法。非USING形式的CONVERT() 是 ODBC 语法,无论使用哪种语法,该函数都返回 NULL,如果 exprNULL

    CONVERT(expr USING transcoding_name) 将数据转换为不同的字符集。在 MySQL 中,转码名与对应的字符集名称相同。例如,这个语句将默认字符集中的字符串 'abc' 转换到 utf8mb4 字符集中:

    SELECT CONVERT('abc' USING utf8mb4);

    CONVERT(expr, type) 语法(不含USING) 将表达式和类型值作为参数,生产指定类型的结果值。这一操作也可以用CAST(expr AS type) 表达式来表示,两者等价。更多信息,请参见CAST() 的描述。

CONVERT() 使用USING子句将数据之间的字符集转换:

CONVERT(expr USING transcoding_name)

在 MySQL 中, transcoding 名称与相应字符集名称相同。

示例:

SELECT CONVERT('test' USING utf8mb4);
SELECT CONVERT(_latin1'Müller' USING utf8mb4);
INSERT INTO utf8mb4_table (utf8mb4_column)
    SELECT CONVERT(latin1_column USING utf8mb4) FROM latin1_table;

要将字符串之间的字符集转换,也可以使用CONVERT(expr, type) 语法(不带USING),或CAST(expr AS type),等价:

CONVERT(string, CHAR[(N)] CHARACTER SET charset_name)
CAST(string AS CHAR[(N)] CHARACTER SET charset_name)

示例:

SELECT CONVERT('test', CHAR CHARACTER SET utf8mb4);
SELECT CAST('test' AS CHAR CHARACTER SET utf8mb4);

如果您像上面所示指定了CHARACTER SET charset_namecharset_name,并且是charset_name的默认排序规则。如果您省略了CHARACTER SET charset_namecharacter_set_connectioncollation_connection系统变量确定,用于确定连接的默认字符集和排序规则(见第12.4节,“连接字符集和排序规则”)。

CONVERT()CAST()调用中不允许指定COLLATE子句,但是可以将其应用于函数结果。例如,这些是合法的:

SELECT CONVERT('test' USING utf8mb4) COLLATE utf8mb4_bin;
SELECT CONVERT('test', CHAR CHARACTER SET utf8mb4) COLLATE utf8mb4_bin;
SELECT CAST('test' AS CHAR CHARACTER SET utf8mb4) COLLATE utf8mb4_bin;

但是这些是不合法的:

SELECT CONVERT('test' USING utf8mb4 COLLATE utf8mb4_bin);
SELECT CONVERT('test', CHAR CHARACTER SET utf8mb4 COLLATE utf8mb4_bin);
SELECT CAST('test' AS CHAR CHARACTER SET utf8mb4 COLLATE utf8mb4_bin);

字符串字面量还可以使用字符集引擎指定。《latin1》和《latin2》在前面的示例中是引擎的实例。与转换函数,如CAST(),或CONVERT()不同的是,引擎将字符串字面量指定为特定的字符集,而不进行转换。更多信息,请参见第12.3.8节,“字符集引擎”

通常,您不能以不区分大小写的方式比较一个BLOB值或其他二进制字符串,因为二进制字符串使用binary字符集,该字符集没有字母大小写的概念。要执行不区分大小写的比较,首先使用CONVERT()CAST()函数将值转换为非二进制字符串。比较结果字符串使用其排序规则。例如,如果转换结果的排序规则不是不区分大小写,那么LIKE操作就不是不区分大小写。这是因为默认utf8mb4排序规则(utf8mb4_0900_ai_ci)不是不区分大小写:

SELECT 'A' LIKE CONVERT(blob_col USING utf8mb4)
  FROM tbl_name;

要为转换后的字符串指定特定的排序规则,使用CONVERT()调用后面的COLLATE子句:

SELECT 'A' LIKE CONVERT(blob_col USING utf8mb4) COLLATE utf8mb4_unicode_ci
  FROM tbl_name;

要使用不同的字符集,替换前面语句中的utf8mb4(类似地使用不同的排序规则)。

CONVERT()CAST()可以用来比较不同字符集中的字符串。例如,这些字符串的比较结果是一个错误,因为它们有不同的字符集:

mysql> SET @s1 = _latin1 'abc', @s2 = _latin2 'abc';
mysql> SELECT @s1 = @s2;
ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT)
and (latin2_general_ci,IMPLICIT) for operation '='

将其中一个字符串转换为与另一个兼容的字符集,使比较操作无错误发生:

mysql> SELECT @s1 = CONVERT(@s2 USING latin1);
+---------------------------------+
| @s1 = CONVERT(@s2 USING latin1) |
+---------------------------------+
|                               1 |
+---------------------------------+

字符集转换也在前置二进制字符串的字母大小写转换时非常有用。LOWER()UPPER() 无法直接应用于二进制字符串,因为字母大小写概念不适用。要对二进制字符串进行字母大小写转换,首先将其转换为适合存储在该字符串中的数据的非二进制字符串:

mysql> SET @str = BINARY 'New York';
mysql> SELECT LOWER(@str), LOWER(CONVERT(@str USING utf8mb4));
+-------------+------------------------------------+
| LOWER(@str) | LOWER(CONVERT(@str USING utf8mb4)) |
+-------------+------------------------------------+
| New York    | new york                           |
+-------------+------------------------------------+

请注意,如果您将BINARYCAST()CONVERT() 应用于索引列,MySQL可能无法高效地使用索引。

CAST()CONVERT() 支持将几何值从一个空间类型转换到另一个空间类型,适用于某些空间类型组合。以下列表显示了允许的类型组合,其中 MySQL 扩展 表示 MySQL 中实现的casts,超出了SQL/MM 标准 定义的casts:

  • Point 到:

    • MultiPoint

    • GeometryCollection

  • LineString 到:

    • Polygon (MySQL 扩展)

    • MultiPoint (MySQL 扩展)

    • MultiLineString

    • GeometryCollection

  • Polygon 到:

    • LineString (MySQL 扩展)

    • MultiLineString (MySQL 扩展)

    • MultiPolygon

    • GeometryCollection

  • MultiPoint 到:

    • Point

    • LineString (MySQL 扩展)

    • GeometryCollection

  • MultiLineString 到:

    • LineString

    • Polygon (MySQL 扩展)

    • MultiPolygon (MySQL 扩展)

    • GeometryCollection

  • MultiPolygon 到:

    • Polygon

    • MultiLineString (MySQL 扩展)

    • GeometryCollection

  • GeometryCollection 到:

    • Point

    • LineString

    • Polygon

    • MultiPoint

    • MultiLineString

    • MultiPolygon

在空间转换中,GeometryCollectionGeomCollection 是同一个结果类型的同义词。

有一些条件适用于所有空间类型转换,还有一些条件只适用于将结果转换为特定的空间类型。关于术语,如““良好几何”,请参阅第13.4.4节,“Geometry Well-Formedness and Validity”

这些条件适用于所有空间转换,无论结果类型是什么:

  • 转换结果在表达式的同一个空间参考系统(SRS)中。

  • 对空间类型之间的转换不改变坐标值或顺序。

  • 如果要转换的表达式是 NULL,函数结果也是 NULL

  • JSON_VALUE() 函数使用指定空间类型的 RETURNING 子句进行转换不允许。

  • 将空间类型转换到 ARRAY 类型不允许。

  • 如果空间类型组合是允许的,但要转换的表达式不是语法正确的几何体,出现ER_GIS_INVALID_DATA 错误。

  • 如果空间类型组合是允许的,但要转换的表达式是一个未定义的空间参考系统(SRS)中的语法正确几何体,出现ER_SRS_NOT_FOUND 错误。

  • 如果要转换的表达式有地理空间 SRS,但经度或纬度超出范围,出现错误:

    显示的范围是度数。如果一个SRS使用另一个单位,范围将使用该单位对应的值。由于浮点算术精度,实际范围限制会有轻微偏差。

当转换结果类型为Point时,这些条件适用:

  • 如果要转换的表达式是一个良好地形状类型为Point,函数结果就是该Point

  • 如果要转换的表达式是一个良好地形状类型为MultiPoint,包含一个Point,函数结果就是该Point。如果表达式中包含多个Point,会出现ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个良好地形状类型为 GeometryCollection,且只包含一个 Point,函数结果就是那个 Point。如果表达式为空、包含多个 Point 或包含其他几何类型,会出现ER_INVALID_CAST_TO_GEOMETRY 错误。

  • 如果要转换的表达式是一个良好地形状类型除 PointMultiPointGeometryCollection 之外的其他几何类型,会出现ER_INVALID_CAST_TO_GEOMETRY 错误。

当转换结果类型为 LineString 时,以下条件适用:

  • 如果要转换的表达式是一个良好地形状类型为 LineString,函数结果就是那个 LineString

  • 如果要转换的表达式是一个良好地形状类型为 Polygon,且没有内环,函数结果是一个包含外环点的顺序相同的 LineString。如果表达式有内环,会出现ER_INVALID_CAST_TO_GEOMETRY 错误。

  • 如果要转换的表达式是一个良好形成的多点几何体,至少包含两个点,那么函数结果是一个包含该多点几何体中点的顺序的线字符串。如果要转换的表达式只包含一个点,则发生ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个良好形成的多线字符串,包含一个线字符串,那么函数结果就是该线字符串。如果要转换的表达式包含多个线字符串,则发生ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个良好形成的几何体集合,包含一个线字符串,那么函数结果就是该线字符串。如果要转换的表达式为空、包含多个线字符串或包含其他几何类型,则发生ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个非LineStringPolygonMultiPointMultiLineStringGeometryCollection类型的良好几何体,会出现ER_INVALID_CAST_TO_GEOMETRY错误。

当转换结果类型是Polygon时,这些条件适用:

  • 如果要转换的表达式是一个良好几何体类型为LineString,且是一个环(即开始和结束点相同),函数结果是一个以LineString点的顺序相同的Polygon。如果不是环,会出现ER_INVALID_CAST_TO_GEOMETRY错误。如果环不正确顺序(外部环必须是逆时针),会出现ER_INVALID_CAST_POLYGON_RING_DIRECTION错误。

  • 如果要转换的表达式是一个良好几何体类型为Polygon,函数结果就是那个Polygon

  • 如果要转换的表达式是一个良好形成的多线性几何类型MultiLineString,其中所有元素都是环,那么函数结果是一个Polygon,第一个LineString作为外部环,任何额外的LineString值作为内部环。如果表达式中的任何元素不是环,出现ER_INVALID_CAST_TO_GEOMETRY错误。 如果环的顺序不正确(外部环必须是逆时针,内部环必须是顺时针),出现ER_INVALID_CAST_POLYGON_RING_DIRECTION错误。

  • 如果要转换的表达式是一个良好形成的多多边形几何类型MultiPolygon,包含一个Polygon,那么函数结果就是那个Polygon。如果表达式中包含多个Polygon,出现ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个良好形成的几何类型为GeometryCollection,且仅包含一个Polygon,函数结果就是该Polygon。如果表达式为空、包含多个Polygon或包含其他几何类型,会出现ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个良好形成的几何类型,除LineStringPolygonMultiLineStringMultiPolygonGeometryCollection外的其他类型,会出现ER_INVALID_CAST_TO_GEOMETRY错误。

当转换结果类型为MultiPoint时,以下条件适用:

  • 如果要转换的表达式是一个良好形成的几何类型为Point,函数结果是一个包含该Point作为唯一元素的MultiPoint

  • 如果要转换的表达式是一个良好形成的几何类型为LineString,函数结果是一个包含LineString中的点顺序相同的MultiPoint

  • 如果要转换的表达式是一个良好形成的几何类型为MultiPoint,函数结果就是该MultiPoint

  • 如果要转换的表达式是一个类型为GeometryCollection的良好几何形状,且只包含点,那么函数结果是一个包含这些点的MultiPoint。如果GeometryCollection为空或包含其他几何形状类型,会出现ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个类型不是PointLineStringMultiPointGeometryCollection的良好几何形状,那么会出现ER_INVALID_CAST_TO_GEOMETRY错误。

当转换结果类型为MultiLineString时,以下条件适用:

  • 如果要转换的表达式是一个类型为LineString的良好几何形状,那么函数结果是一个包含该LineString作为其唯一元素的MultiLineString

  • 如果要转换的表达式是一个类型为Polygon的良好几何形状,那么函数结果是一个包含该Polygon外环作为其第一个元素,且包含该Polygon中的所有内环作为顺序出现的额外元素的MultiLineString

  • 如果要转换的表达式是一个类型为MultiLineString的良好几何形状,那么函数结果就是该MultiLineString

  • 如果要转换的表达式是一个良好形成的多边形类型MultiPolygon,只包含不含内环的多边形,那么函数结果是一个MultiLineString,包含表达式中出现的多边形环顺序。如果表达式包含任何多边形有内环,会发生ER_WRONG_PARAMETERS_TO_STORED_FCT错误。

  • 如果要转换的表达式是一个良好形成的几何类型GeometryCollection,只包含线字符串,那么函数结果是一个MultiLineString,包含这些线字符串。如果表达式为空或包含其他几何类型,会发生ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个除LineStringPolygonMultiLineStringMultiPolygonGeometryCollection之外的几何类型,会发生ER_INVALID_CAST_TO_GEOMETRY错误。

当转换结果类型是MultiPolygon时,这些条件适用:

  • 如果要转换的表达式是一个良好形成的多边形类型Polygon,函数结果是一个MultiPolygon,包含该多边形作为其唯一元素。

  • 如果要转换的表达式是一个良好形成的多线性几何类型MultiLineString,其中所有元素都是环,那么函数结果是一个MultiPolygon,包含每个元素的一个Polygon,只有外部环。任何一个元素不是环,或者环的顺序不正确(外部环必须是逆时针),都会出现ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个良好形成的多多边形几何类型MultiPolygon,那么函数结果就是那个MultiPolygon

  • 如果要转换的表达式是一个良好形成的几何集合类型GeometryCollection,只包含多边形,那么函数结果是一个MultiPolygon,包含那些多边形。如果表达式为空或包含其他几何类型,会出现ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个非PolygonMultiLineStringMultiPolygonGeometryCollection类型的良好几何体,会出现ER_INVALID_CAST_TO_GEOMETRY错误。

当转换结果类型为GeometryCollection时,这些条件适用:

  • GeometryCollectionGeomCollection是同一个结果类型的同义词。

  • 如果要转换的表达式是一个良好几何体类型为Point,函数结果是一个包含该Point作为唯一元素的GeometryCollection

  • 如果要转换的表达式是一个良好几何体类型为LineString,函数结果是一个包含该LineString作为唯一元素的GeometryCollection

  • 如果要转换的表达式是一个良好几何体类型为Polygon,函数结果是一个包含该Polygon作为唯一元素的GeometryCollection

  • 如果要转换的表达式是一个良好几何体类型为MultiPoint,函数结果是一个包含表达式中点的顺序的GeometryCollection

  • 如果要转换的表达式是一个良好形成的几何类型MultiLineString,函数结果是一个包含线estring顺序出现的GeometryCollection

  • 如果要转换的表达式是一个良好形成的几何类型MultiPolygon,函数结果是一个包含MultiPolygon顺序出现的GeometryCollection

  • 如果要转换的表达式是一个良好形成的几何类型GeometryCollection,函数结果就是该GeometryCollection

CAST() 函数在CREATE TABLE ... SELECT 语句中创建一个特定的列类型非常有用。

mysql> CREATE TABLE new_table SELECT CAST('2000-01-01' AS DATE) AS c1;
mysql> SHOW CREATE TABLE new_table\G
*************************** 1. row ***************************
       Table: new_table
Create Table: CREATE TABLE `new_table` (
  `c1` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

CAST() 函数也可以用于对ENUM 列进行字典顺序排序。通常,ENUM 列的排序是使用内部数字值。将值转换为CHAR 就可以实现字典顺序排序:

SELECT enum_col FROM tbl_name 
  ORDER BY CAST(enum_col AS CHAR);

CAST() 也会在使用它作为更复杂表达式的一部分时改变结果,例如CONCAT('Date: ',CAST(NOW() AS DATE))

对于时间值,很少需要使用CAST()来提取数据以不同格式。相反,可以使用函数如EXTRACT()DATE_FORMAT()TIME_FORMAT()。见第14.7节,“日期和时间函数”.

将字符串转换为数字,通常只需要在数值上下文中使用该字符串值:

mysql> SELECT 1+'1';
       -> 2

同样也适用于十六进制和位字面量,它们默认是二进制字符串:

mysql> SELECT X'41', X'41'+0;
        -> 'A', 65
mysql> SELECT b'1100001', b'1100001'+0;
        -> 'a', 97

在表达式求值时,将字符串用作算术操作将被转换为浮点数。

将数字用作字符串上下文将被转换为字符串:

mysql> SELECT CONCAT('hello you ',2);
        -> 'hello you 2'

关于隐式将数字转换为字符串的信息,见第14.3节,“表达式求值中的类型转换”.

MySQL 支持对有符号和无符号 64 位整数进行算术运算。对于数字操作符(例如+-),其中一个操作数是无符号整数,结果默认为无符号(见第14.6.1节,“算术运算符”)。要覆盖这个规则,可以使用SIGNEDUNSIGNED强制类型转换操作符将值强制转换为有符号或无符号 64 位整数,分别。

mysql> SELECT 1 - 2;
        -> -1
mysql> SELECT CAST(1 - 2 AS UNSIGNED);
        -> 18446744073709551615
mysql> SELECT CAST(CAST(1 - 2 AS UNSIGNED) AS SIGNED);
        -> -1

如果任意一个操作数是浮点值,则结果是浮点值,并且不受前面规则的影响。在这个上下文中,DECIMAL 列值被视为浮点值。

mysql> SELECT CAST(1 AS UNSIGNED) - 2.0;
        -> -1.0

SQL 模式影响转换操作的结果(见第7.1.11节,“服务器 SQL 模式”)。示例:

  • 将“”日期字符串转换为日期时,CONVERT()CAST() 返回 NULL 并在启用NO_ZERO_DATE SQL 模式时产生警告。

  • 对于整数减法,如果启用了NO_UNSIGNED_SUBTRACTION SQL 模式,结果即使其中任何操作数是无符号的,也会是有符号的。