文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  函数和运算符  /  强制转换函数和运算符

14.10 强制转换函数和运算符

表 14.15 强制转换函数和运算符

名称 说明 已弃用
BINARY 将字符串转换为二进制字符串
CAST() 将值强制转换为特定类型
CONVERT() 将值强制转换为特定类型

强制转换函数和运算符支持将值从一种数据类型转换为另一种数据类型。

强制转换函数和运算符说明

  • BINARY expr

    BINARY 运算符将表达式转换为二进制字符串(具有 binary 字符集和 binary 排序规则的字符串)。BINARY 的常见用途是强制使用数值字节值而不是逐个字符地进行逐字节字符串比较。BINARY 运算符还会导致比较中的尾随空格变得重要。有关 binary 字符集的 binary 排序规则与非二进制字符集的 _bin 排序规则之间的区别的信息,请参阅 第 12.8.5 节“二进制排序规则与 _bin 排序规则的比较”

    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

    如果从 mysql 客户端调用 BINARY,则二进制字符串将使用十六进制表示法显示,具体取决于 --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),两者等效。如果 exprNULL,则 CAST() 返回 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]

      生成一个具有 VARCHAR 数据类型的字符串,除非表达式 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 值。以下规则 governing conversion to 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 允许使用额外的 ARRAY 关键字,以便在 CREATE INDEXCREATE TABLEALTER TABLE 语句中创建 JSON 数组上的多值索引。ARRAY 仅在用于在这些语句之一中创建多值索引时才受支持,在这种情况下是必需的。正在编制索引的列必须是 JSON 类型的列。使用 ARRAY 时,AS 关键字后面的 type 可以指定 CAST() 支持的任何类型,但 BINARYJSONYEAR 除外。有关语法信息和示例,以及其他相关信息,请参阅 多值索引

    注意

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

    CAST() 支持使用 AT TIMEZONE 运算符检索 TIMESTAMP 值(以 UTC 表示)。唯一支持的时区是 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' 用作此形式的 CAST() 的时区说明符,并且服务器引发了诸如 未知或不正确的时区:'UTC' 之类的错误,则可能需要安装 MySQL 时区表(请参阅 填充时区表)。

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

  • CONVERT(expr USING transcoding_name)

    CONVERT(expr,type)

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

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

    SELECT CONVERT('abc' USING utf8mb4);

    CONVERT(expr, type) 语法(不带 USING)接受一个表达式和一个指定结果类型的 type 值,并生成指定类型的结果值。此操作也可以表示为 CAST(expr AS type),两者是等效的。有关更多信息,请参阅 CAST() 的说明。

字符集转换

带有 USING 子句的 CONVERT() 在字符集之间转换数据

CONVERT(expr USING transcoding_name)

在 MySQL 中,转码名称与相应的字符集名称相同。

示例

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_name,则结果的字符集和排序规则为 charset_namecharset_name 的默认排序规则。如果省略 CHARACTER SET charset_name,则结果的字符集和排序规则由确定默认连接字符集和排序规则的 character_set_connectioncollation_connection 系统变量定义(请参阅 第 12.4 节“连接字符集和排序规则”)。

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

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 扩展”表示在 SQL/MM 标准 中定义的强制转换之外,MySQL 中实现的强制转换:

  • 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 节“几何图形的格式良好性和有效性”

空间强制转换的一般条件

这些条件适用于所有空间强制转换,无论结果类型如何:

  • 强制转换的结果与要强制转换的表达式的 SRS 相同。

  • 在空间类型之间强制转换不会更改坐标值或顺序。

  • 如果要强制转换的表达式为 NULL,则函数结果为 NULL

  • 不允许使用 JSON_VALUE() 函数进行空间类型强制转换,其中 RETURNING 子句指定了空间类型。

  • 不允许强制转换为空间类型的 ARRAY

  • 如果允许空间类型组合,但要强制转换的表达式不是语法上格式良好的几何图形,则会发生 ER_GIS_INVALID_DATA 错误。

  • 如果允许空间类型组合,但要强制转换的表达式是在未定义的空间参考系统 (SRS) 中的语法上格式良好的几何图形,则会发生 ER_SRS_NOT_FOUND 错误。

  • 如果要强制转换的表达式具有地理 SRS,但其经度或纬度超出范围,则会发生错误:

    显示的范围以度为单位。如果 SRS 使用其他单位,则范围使用其单位中的相应值。由于浮点运算,确切的范围限制略有偏差。

强制转换为 Point 的条件

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

  • 如果要强制转换的表达式是类型为 Point 的格式良好的几何图形,则函数结果为该 Point

  • 如果要强制转换的表达式是包含单个 Point 的类型为 MultiPoint 的格式良好的几何图形,则函数结果为该 Point。如果表达式包含多个 Point,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

  • 如果要强制转换的表达式是仅包含单个 Point 的类型为 GeometryCollection 的格式良好的几何图形,则函数结果为该 Point。如果表达式为空、包含多个 Point 或包含其他几何图形类型,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

  • 如果要强制转换的表达式是类型不是 PointMultiPointGeometryCollection 的格式良好的几何图形,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

强制转换为 LineString 的条件

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

  • 如果要强制转换的表达式是类型为 LineString 的格式良好的几何图形,则函数结果为该 LineString

  • 如果要强制转换的表达式是类型为 Polygon 且没有内环的格式良好的几何图形,则函数结果是一个 LineString,其中包含外环的点,顺序相同。如果表达式具有内环,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

  • 如果要强制转换的表达式是包含至少两个点的类型为 MultiPoint 的格式良好的几何图形,则函数结果是一个 LineString,其中包含 MultiPoint 的点,顺序与它们在表达式中出现的顺序相同。如果表达式仅包含一个 Point,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

  • 如果要强制转换的表达式是包含单个 LineString 的类型为 MultiLineString 的格式良好的几何图形,则函数结果为该 LineString。如果表达式包含多个 LineString,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

  • 如果要强制转换的表达式是类型为 GeometryCollection 且仅包含单个 LineString 的格式良好的几何图形,则函数结果为该 LineString。如果表达式为空、包含多个 LineString 或包含其他几何图形类型,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

  • 如果要强制转换的表达式是类型不是 LineStringPolygonMultiPointMultiLineStringGeometryCollection 的格式良好的几何图形,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

强制转换为 Polygon 的条件

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

  • 如果要转换的表达式是类型为 LineString 的格式正确的几何图形,并且它是一个环(即起点和终点相同),则函数结果是一个 Polygon,其外环由 LineString 的点以相同的顺序组成。如果表达式不是环,则会发生 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 的条件

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

  • 如果要转换的表达式是类型为 Point 的格式正确的几何图形,则函数结果是一个 MultiPoint,其中包含该 Point 作为其唯一元素。

  • 如果要转换的表达式是类型为 LineString 的格式正确的几何图形,则函数结果是一个 MultiPoint,其中包含 LineString 的点,顺序相同。

  • 如果要转换的表达式是类型为 MultiPoint 的格式正确的几何图形,则函数结果是该 MultiPoint

  • 如果要转换的表达式是类型为 GeometryCollection 的格式正确的几何图形,并且仅包含点,则函数结果是一个 MultiPoint,其中包含这些点。如果 GeometryCollection 为空或包含其他几何图形类型,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

  • 如果要转换的表达式是类型为除 PointLineStringMultiPointGeometryCollection 以外的格式正确的几何图形,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

转换为 MultiLineString 的条件

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

  • 如果要转换的表达式是类型为 LineString 的格式正确的几何图形,则函数结果是一个 MultiLineString,其中包含该 LineString 作为其唯一元素。

  • 如果要转换的表达式是类型为 Polygon 的格式正确的几何图形,则函数结果是一个 MultiLineString,其中包含 Polygon 的外环作为其第一个元素,并按其在表达式中出现的顺序将任何内环作为其他元素。

  • 如果要转换的表达式是类型为 MultiLineString 的格式正确的几何图形,则函数结果是该 MultiLineString

  • 如果要转换的表达式是类型为 MultiPolygon 的格式正确的几何图形,并且仅包含没有内环的多边形,则函数结果是一个 MultiLineString,其中包含按其在表达式中出现的顺序排列的多边形环。如果表达式包含任何具有内环的多边形,则会发生 ER_WRONG_PARAMETERS_TO_STORED_FCT 错误。

  • 如果要转换的表达式是类型为 GeometryCollection 的格式正确的几何图形,并且仅包含线串,则函数结果是一个 MultiLineString,其中包含这些线串。如果表达式为空或包含其他几何图形类型,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

  • 如果要转换的表达式是类型为除 LineStringPolygonMultiLineStringMultiPolygonGeometryCollection 以外的格式正确的几何图形,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

转换为 MultiPolygon 的条件

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

  • 如果要转换的表达式是类型为 Polygon 的格式正确的几何图形,则函数结果是一个 MultiPolygon,其中包含该 Polygon 作为其唯一元素。

  • 如果要转换的表达式是类型为 MultiLineString 的格式正确的几何图形,并且所有元素都是环,则函数结果是一个 MultiPolygon,其中包含一个 Polygon,该 Polygon 仅包含表达式的每个元素的外环。如果任何元素不是环,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。如果任何环的顺序不正确(外环必须为逆时针方向),则会发生 ER_INVALID_CAST_POLYGON_RING_DIRECTION 错误。

  • 如果要转换的表达式是类型为 MultiPolygon 的格式正确的几何图形,则函数结果是该 MultiPolygon

  • 如果要转换的表达式是类型为 GeometryCollection 的格式正确的几何图形,并且仅包含多边形,则函数结果是一个 MultiPolygon,其中包含这些多边形。如果表达式为空或包含其他几何图形类型,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

  • 如果要转换的表达式是类型为除 PolygonMultiLineStringMultiPolygonGeometryCollection 以外的格式正确的几何图形,则会发生 ER_INVALID_CAST_TO_GEOMETRY 错误。

转换为 GeometryCollection 的条件

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

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

  • 如果要转换的表达式是类型为 Point 的格式正确的几何图形,则函数结果是一个 GeometryCollection,其中包含该 Point 作为其唯一元素。

  • 如果要转换的表达式是类型为 LineString 的格式正确的几何图形,则函数结果是一个 GeometryCollection,其中包含该 LineString 作为其唯一元素。

  • 如果要转换的表达式是类型为 Polygon 的格式正确的几何图形,则函数结果是一个 GeometryCollection,其中包含该 Polygon 作为其唯一元素。

  • 如果要转换的表达式是类型为 MultiPoint 的格式正确的几何图形,则函数结果是一个 GeometryCollection,其中包含按其在表达式中出现的顺序排列的点。

  • 如果要转换的表达式是类型为 MultiLineString 的格式正确的几何图形,则函数结果是一个 GeometryCollection,其中包含按其在表达式中出现的顺序排列的线串。

  • 如果要转换的表达式是类型为 MultiPolygon 的格式正确的几何图形,则函数结果是一个 GeometryCollection,其中包含按其在表达式中出现的顺序排列的 MultiPolygon 的元素。

  • 如果要转换的表达式是类型为 GeometryCollection 的格式正确的几何图形,则函数结果是该 GeometryCollection

转换操作的其他用途

转换函数可用于在 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

转换函数可用于按词典顺序对 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 模式”)。例如:

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

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