类型转换函数和操作符使得从一种数据类型到另一种数据类型的值转换成为可能。
-
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
在
CHAR
、VARCHAR
或TEXT
列定义中使用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(
timestamp_value
AT TIME ZONEtimezone_specifier
AS DATETIME[(precision
)])timezone_specifier
: [INTERVAL] '+00:00' | 'UTC'使用
CAST(
语法,expr
AStype
CAST()
函数将任何类型的表达式转换为指定类型的结果值。该操作也可以用CONVERT(
表示,它们是等效的。如果expr
,type
)expr
是NULL
,CAST()
返回NULL
。以下
type
值是允许的:-
BINARY[(
N
)]生成一个具有
VARBINARY
数据类型的字符串,除非表达式expr
是空的(零长度),结果类型是BINARY(0)
。如果提供了可选的长度N
,BINARY(
导致转换使用不超过N
)N
字节的参数。短于N
字节的值将用0x00
字节填充到长度N
。如果不提供可选的长度N
,MySQL 将从表达式中计算最大长度。如果提供或计算的长度超过内部阈值,结果类型是BLOB
。如果长度仍然太长,结果类型是LONGBLOB
。有关将值转换为
BINARY
对比较的影响的描述,请参阅 第 13.3.3 节,“二进制和 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
-
ASCII
:CHARACTER SET latin1
的简写。 -
UNICODE
:CHARACTER SET ucs2
的简写。
在所有情况下,字符串都具有默认字符集的排序规则。
-
-
DATE
生成一个
DATE
值。 -
DATETIME[(
M
)]生成一个
DATETIME
值。如果给定可选的M
值,它指定了小数秒精度。 -
DECIMAL[(
M
[,D
])]生成一个
DECIMAL
值。如果给定可选的M
和D
值,它们指定了最大数字(精度)和小数点后的数字(规模)。如果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。
-
对于
DATE
、DATETIME
或TIMESTAMP
值,返回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 | +--------------------------+-------------------------------+
-
如果参数的类型是
DECIMAL
、DOUBLE
、DECIMAL
或REAL
,将值四舍五入到最近的整数,然后尝试使用整数值的规则将其转换为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 | +---------------------+---------------------+
-
对于无法成功转换为
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 INDEX
、CREATE TABLE
和ALTER TABLE
语句的一部分。ARRAY
只在这些语句中创建多值索引时支持,否则不支持。被索引的列必须是JSON
类型的列。使用ARRAY
时,type
关键字后面的类型可以是CAST()
支持的任何类型,除了BINARY
、JSON
和YEAR
。有关语法信息和示例,以及其他相关信息,请参阅 多值索引。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
USINGtranscoding_name
)CONVERT(
是标准 SQL 语法。无expr
USINGtranscoding_name
)USING
形式的CONVERT()
是 ODBC 语法。不管使用哪种语法,该函数如果expr
是NULL
,则返回NULL
。CONVERT(
在不同的字符集之间转换数据。在 MySQL 中,transcoding 名称与对应的字符集名称相同。例如,这个语句将默认字符集中的字符串expr
USINGtranscoding_name
)'abc'
转换为utf8mb4
字符集中的对应字符串:SELECT CONVERT('abc' USING utf8mb4);
CONVERT(
语法(无expr
,type
)USING
)将表达式和指定结果类型的值type
,并生成指定类型的结果值。该操作也可以用CAST(
表示,它们是等效的。有关更多信息,请参阅expr
AStype
)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_name
和charset_name
的默认排序规则。如果您省略CHARACTER SET
,结果的字符集和排序规则将由charset_name
character_set_connection
和collation_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 |
+-------------+------------------------------------+
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
-
在空间类型转换中,GeometryCollection
和 GeomCollection
是同一结果类型的同义词。
所有空间类型转换都有一些通用条件,一些条件仅适用于特定空间类型的结果。有关术语,如 “良好形成的几何体,” 请参阅 第 13.4.4 节,“几何体良好形成和有效性”。
空间投射的通用条件
这些条件适用于所有空间投射,不管结果类型如何:
-
投射结果的SRS与要投射的表达式的SRS相同。
-
在空间类型之间进行投射时,不会改变坐标值或顺序。
-
如果要投射的表达式为
NULL
,函数结果为NULL
。 -
使用
JSON_VALUE()
函数带有RETURNING
子句指定空间类型的投射不被允许。 -
将空间类型投射到
ARRAY
中不被允许。 -
如果空间类型组合是允许的,但要投射的表达式不是语法正确的几何体,将发生
ER_GIS_INVALID_DATA
错误。 -
如果空间类型组合是允许的,但要投射的表达式是一个语法正确的几何体,但在未定义的空间参考系统(SRS)中,将发生
ER_SRS_NOT_FOUND
错误。 -
如果要投射的表达式具有地理SRS,但具有超出范围的经度或纬度,将发生错误:
-
如果经度值不在范围(−180,180]内,将发生
ER_GEOMETRY_PARAM_LONGITUDE_OUT_OF_RANGE
错误。 -
如果纬度值不在范围[−90,90]内,将发生
ER_GEOMETRY_PARAM_LATITUDE_OUT_OF_RANGE
错误。
显示的范围以度为单位。如果SRS使用其他单位,范围将使用该单位对应的值。由于浮点数算术,确切的范围限制略有偏差。
-
点类型强制转换的条件
当强制转换结果类型为Point
时,以下条件适用:
-
如果要强制转换的表达式是一个格式正确的
Point
几何体,则函数结果是该Point
。 -
如果要强制转换的表达式是一个格式正确的
MultiPoint
几何体,包含一个Point
,则函数结果是该Point
。如果表达式包含多个Point
,将发生ER_INVALID_CAST_TO_GEOMETRY
错误。 -
如果要强制转换的表达式是一个格式正确的
GeometryCollection
几何体,仅包含一个Point
,则函数结果是该Point
。如果表达式为空、包含多个Point
或包含其他几何类型,将发生ER_INVALID_CAST_TO_GEOMETRY
错误。 -
如果要强制转换的表达式是一个格式正确的几何体,但类型不是
Point
、MultiPoint
或GeometryCollection
,将发生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
错误。 -
如果要转换的表达式是一个良好形成的几何体类型不是
LineString
、Polygon
、MultiPoint
、MultiLineString
或GeometryCollection
,将发生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
错误。 -
如果要转换的表达式是一个类型不是
LineString
、Polygon
、MultiLineString
、MultiPolygon
或GeometryCollection
的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
错误。 -
如果要转换的表达式是一个类型不是
Point
、LineString
、MultiPoint
或GeometryCollection
的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
错误。 -
如果要转换的表达式是一个格式正确的几何类型,而不是
LineString
、Polygon
、MultiLineString
、MultiPolygon
或GeometryCollection
,则会出现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几何体,类型不是
Polygon
、MultiLineString
、MultiPolygon
或GeometryCollection
,将发生ER_INVALID_CAST_TO_GEOMETRY
错误。
GeometryCollection类型转换的条件
当转换结果类型为GeometryCollection
时,以下条件适用:
-
GeometryCollection
和GeomCollection
是同一结果类型的同义词。 -
如果要转换的表达式是一个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
。
强制转换函数对于在 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 节,“算术运算符”)。要覆盖此行为,请使用 SIGNED
或 UNSIGNED
强制转换运算符将值强制转换为有符号或无符号 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 模式,那么减法结果是有符号的,即使任何操作数是无符号的。