Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

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

14.10 类型转换函数和操作符

表 14.15 类型转换函数和操作符

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

类型转换函数和操作符使得从一种数据类型到另一种数据类型的值转换成为可能。

类型转换函数和操作符描述

  • BINARY expr

    The BINARY 操作符将表达式转换为二进制字符串(一个具有 binary 字符集和 binary 排序的字符串)。BINARY 操作符的一个常见用途是强制字符字符串比较按字节顺序进行比较,而不是字符顺序比较。 BINARY 操作符还使得比较中的尾随空格变得重要。关于 binary 字符集的 binary 排序和非二进制字符集的 _bin 排序之间的差异,请参见 第 12.8.5 节,“二进制排序与_bin 排序的比较”

    The 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) 表示,它们是等效的。如果 exprNULLCAST() 返回 NULL

    以下 type 值是允许的:

    • BINARY[(N)]

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

      有关将值转换为 BINARY 对比较的影响的描述,请参阅 第 13.3.3 节,“二进制和 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

      生成一个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 的结果。这实际上是 FLOAT,如果启用了 REAL_AS_FLOAT SQL 模式;否则结果为类型 DOUBLE

    • SIGNED [INTEGER]

      生成有符号的 BIGINT 值。

    • spatial_type

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

    • TIME[(M)]

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

    • 无符号 [INTEGER]

      生成一个无符号的 BIGINT 值。

    • YEAR

      生成一个 YEAR 值。以下规则 govern 转换为 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 只在这些语句中创建多值索引时支持,否则不支持。被索引的列必须是 JSON 类型的列。使用 ARRAY 时,type 关键字后面的类型可以是 CAST() 支持的任何类型,除了 BINARYJSONYEAR。有关语法信息和示例,以及其他相关信息,请参阅 多值索引

    Note

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

    CAST() 支持以 UTC 时间戳形式检索 TIMESTAMP 值,使用 AT TIMEZONE 运算符。唯一支持的时区是 UTC,可以指定为 '+00:00''UTC'。该语法仅支持 DATETIME 返回类型,带有可选的精度specifier,范围从 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' 作为时区specifier与该形式的 CAST(),并且服务器引发错误,如 未知或不正确的时区:'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 中,transcoding 名称与对应的字符集名称相同。例如,这个语句将默认字符集中的字符串 '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 中,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_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与要投射的表达式的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 错误。

  • 如果要转换的表达式是一个良好形成的几何体类型为 MultiPoint,包含至少两个点,那么函数结果是一个包含 MultiPoint 中点的 LineString,点的顺序与原始几何体相同。如果表达式只包含一个 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 时,以下条件适用:

  • 如果要转换的表达式是一个良好形成的几何体类型为 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的well-formed几何体,则会发生ER_INVALID_CAST_TO_GEOMETRY错误。

转换为MultiPoint的条件

当cast结果类型是MultiPoint时,以下条件适用:

  • 如果要转换的表达式是一个类型为Point的well-formed几何体,则函数结果是一个包含该Point作为其唯一元素的MultiPoint

  • 如果要转换的表达式是一个类型为LineString的well-formed几何体,则函数结果是一个包含LineString点的MultiPoint,点的顺序与LineString相同。

  • 如果要转换的表达式是一个类型为MultiPoint的well-formed几何体,则函数结果是该MultiPoint

  • 如果要转换的表达式是一个类型为GeometryCollection的well-formed几何体,仅包含点,则函数结果是一个包含这些点的MultiPoint。如果GeometryCollection为空或包含其他几何类型,则会发生ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个类型不是PointLineStringMultiPointGeometryCollection的well-formed几何体,则会发生ER_INVALID_CAST_TO_GEOMETRY错误。

转换为MultiLineString的条件

当cast结果类型是MultiLineString时,以下条件适用:

  • 如果要转换的表达式是一个类型为LineString的well-formed几何体,则函数结果是一个包含该LineString作为其唯一元素的MultiLineString

  • 如果要转换的表达式是一个类型为Polygon的well-formed几何体,则函数结果是一个包含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

  • 如果要转换的表达式是一个well-formed几何体,类型为GeometryCollection,包含仅有多边形,那么函数结果是一个MultiPolygon,包含这些多边形。如果表达式为空或包含其他几何体类型,将发生ER_INVALID_CAST_TO_GEOMETRY错误。

  • 如果要转换的表达式是一个well-formed几何体,类型不是PolygonMultiLineStringMultiPolygonGeometryCollection,将发生ER_INVALID_CAST_TO_GEOMETRY错误。

GeometryCollection类型转换的条件

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

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

  • 如果要转换的表达式是一个well-formed几何体,类型为Point,那么函数结果是一个GeometryCollection,包含该Point作为其唯一元素。

  • 如果要转换的表达式是一个well-formed几何体,类型为LineString,那么函数结果是一个GeometryCollection,包含该LineString作为其唯一元素。

  • 如果要转换的表达式是一个well-formed几何体,类型为Polygon,那么函数结果是一个GeometryCollection,包含该Polygon作为其唯一元素。

  • 如果要转换的表达式是一个well-formed几何体,类型为MultiPoint,那么函数结果是一个GeometryCollection,包含表达式中的点,以它们出现的顺序。

  • 如果要转换的表达式是一个well-formed几何体,类型为MultiLineString,那么函数结果是一个GeometryCollection,包含表达式中的线串,以它们出现的顺序。

  • 如果要转换的表达式是一个well-formed几何体,类型为MultiPolygon,那么函数结果是一个GeometryCollection,包含MultiPolygon中的元素,以它们出现的顺序。

  • 如果要转换的表达式是一个well-formed几何体,类型为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

强制转换函数对于按词典顺序对 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

这也适用于十六进制和位 literals,它们默认是二进制字符串:

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 模式,那么减法结果是有符号的,即使任何操作数是无符号的。