文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  函数和运算符  /  转换函数和运算符

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)。如果给出了可选的长度NCHAR(N)会导致强制转换使用不超过N个字符的论据。对于小于N个字符的值,不会进行填充。如果未给出可选长度N,MySQL 将从表达式中计算最大长度。如果提供的或计算出的长度大于内部阈值,则结果类型为TEXT。如果长度仍然过长,则结果类型为LONGTEXT

      如果没有charset_info子句,CHAR将生成一个具有默认字符集的字符串。若要显式指定字符集,则允许使用以下charset_info

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

      • ASCIICHARACTER SET latin1的简写。

      • UNICODECHARACTER SET ucs2的简写。

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

    • 日期

      生成一个DATE值。

    • DATETIME[(M)]

      生成一个DATETIME值。如果给出了可选的M值,则它指定小数秒精度。

    • DECIMAL[(M[,D])]

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

    • 双精度

      生成一个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_AS_FLOAT SQL 模式,这实际上是FLOAT;否则结果类型为DOUBLE

    • 带符号 [整数]

      生成一个带符号的BIGINT值。

    • 空间类型

      CAST()CONVERT()支持将几何值从一种空间类型转换为另一种空间类型,适用于某些空间类型的组合。有关详细信息,请参阅空间类型上的强制转换操作

    • 时间[(M)]

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

    • 无符号 [整数]

      生成一个无符号的BIGINT值。

    • 生成一个YEAR值。以下规则管理转换为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关键字在JSON数组上创建多值索引,作为CREATE INDEXCREATE TABLEALTER TABLE语句的一部分。ARRAY仅在用于在这些语句之一中创建多值索引时才受支持,在这种情况下,它是必需的。被索引的列必须是类型为JSON的列。使用ARRAY时,AS关键字后的type可以指定CAST()支持的任何类型,除了BINARYJSONYEAR。有关语法信息和示例,以及其他相关信息,请参阅多值索引

    注意

    CONVERT()CAST()不同,不支持创建多值索引或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()的时区说明符,并且服务器引发了诸如Unknown or incorrect time zone: 'UTC'之类的错误,您可能需要安装 MySQL 时区表(请参阅填充时区表)。

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

  • CONVERT(expr USING transcoding_name)

    CONVERT(expr,type)

    CONVERT(expr USING transcoding_name)是标准 SQL 语法。非USING形式的CONVERT()是 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()的描述。

字符集转换

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

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 节,“连接字符集和排序规则”)。

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 中实现的强制转换,超出 SQL/MM 标准 中定义的强制转换

  • 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

  • 如果要强制转换的表达式是类型为 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 的格式良好的几何形状,则函数结果为该 LineString

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

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

  • 如果要强制转换的表达式是类型为 MultiLineString 的格式良好的几何形状,并且包含单个 LineString,则函数结果为该 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,每个表达式元素仅包含一个外环。如果任何元素不是环,则会发生 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 模式”)。示例

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

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