14.10 转换函数和运算符
转换函数和运算符使得可以将值从一个数据类型转换到另一个数据类型。
-
BINARYexprBINARY运算符将表达式转换为二进制字符串(一个具有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 '; -> 0BINARY在比较操作中影响整个操作;它可以在两个操作数前面使用,结果相同。将字符串表达式转换为二进制字符串,这些构造是等价的: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如果从
BINARY在mysql客户端中调用,二进制字符串将以十六进制表示,取决于--binary-as-hex的值。关于该选项的更多信息,请参见第6.5.1节,“mysql — MySQL 命令行客户端”. -
CAST(timestamp_valueAT TIME ZONEtimezone_specifierAS DATETIME[(precision)])timezone_specifier: [INTERVAL] '+00:00' | 'UTC'使用
CAST(语法,exprAStypeCAST()函数将任何类型的表达式转换为指定类型的结果值。这一操作也可以用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节,“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 -
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的结果。如果启用了REAL_AS_FLOATSQL 模式,那么实际上是FLOAT;否则结果为类型DOUBLE。 -
SIGNED [INTEGER]产生一个有符号
BIGINT值。 -
spatial_typeCAST()和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。
-
对于
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关键字。除非在这些语句中用于创建多值索引,否则不支持。ARRAY所指的列必须是类型为JSON的列。使用ARRAY时,type关键字后可以指定CAST()支持的任何类型,除了BINARY、JSON和YEAR。语法信息、示例和其他相关信息,请参见多值索引。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(exprUSINGtranscoding_name)CONVERT(是标准SQL语法。非exprUSINGtranscoding_name)USING形式的CONVERT()是 ODBC 语法,无论使用哪种语法,该函数都返回NULL,如果expr是NULL。CONVERT(将数据转换为不同的字符集。在 MySQL 中,转码名与对应的字符集名称相同。例如,这个语句将默认字符集中的字符串exprUSINGtranscoding_name)'abc'转换到utf8mb4字符集中:SELECT CONVERT('abc' USING utf8mb4);CONVERT(语法(不含expr,type)USING) 将表达式和类型值作为参数,生产指定类型的结果值。这一操作也可以用CAST(表达式来表示,两者等价。更多信息,请参见exprAStype)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_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 中实现的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
-
在空间转换中,GeometryCollection 和 GeomCollection 是同一个结果类型的同义词。
有一些条件适用于所有空间类型转换,还有一些条件只适用于将结果转换为特定的空间类型。关于术语,如““良好几何”,请参阅第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,但经度或纬度超出范围,出现错误:
-
如果经度值不在范围(-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错误。 -
如果要转换的表达式是一个良好形成的多点几何体,至少包含两个点,那么函数结果是一个包含该多点几何体中点的顺序的线字符串。如果要转换的表达式只包含一个点,则发生
ER_INVALID_CAST_TO_GEOMETRY错误。 -
如果要转换的表达式是一个良好形成的多线字符串,包含一个线字符串,那么函数结果就是该线字符串。如果要转换的表达式包含多个线字符串,则发生
ER_INVALID_CAST_TO_GEOMETRY错误。 -
如果要转换的表达式是一个良好形成的几何体集合,包含一个线字符串,那么函数结果就是该线字符串。如果要转换的表达式为空、包含多个线字符串或包含其他几何类型,则发生
ER_INVALID_CAST_TO_GEOMETRY错误。 -
如果要转换的表达式是一个非
LineString、Polygon、MultiPoint、MultiLineString或GeometryCollection类型的良好几何体,会出现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错误。 -
如果要转换的表达式是一个良好形成的几何类型,除
LineString、Polygon、MultiLineString、MultiPolygon或GeometryCollection外的其他类型,会出现ER_INVALID_CAST_TO_GEOMETRY错误。
当转换结果类型为MultiPoint时,以下条件适用:
-
如果要转换的表达式是一个良好形成的几何类型为
Point,函数结果是一个包含该Point作为唯一元素的MultiPoint。 -
如果要转换的表达式是一个良好形成的几何类型为
LineString,函数结果是一个包含LineString中的点顺序相同的MultiPoint。 -
如果要转换的表达式是一个良好形成的几何类型为
MultiPoint,函数结果就是该MultiPoint。 -
如果要转换的表达式是一个类型为
GeometryCollection的良好几何形状,且只包含点,那么函数结果是一个包含这些点的MultiPoint。如果GeometryCollection为空或包含其他几何形状类型,会出现ER_INVALID_CAST_TO_GEOMETRY错误。 -
如果要转换的表达式是一个类型不是
Point、LineString、MultiPoint或GeometryCollection的良好几何形状,那么会出现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错误。 -
如果要转换的表达式是一个除
LineString、Polygon、MultiLineString、MultiPolygon或GeometryCollection之外的几何类型,会发生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错误。 -
如果要转换的表达式是一个非
Polygon、MultiLineString、MultiPolygon或GeometryCollection类型的良好几何体,会出现ER_INVALID_CAST_TO_GEOMETRY错误。
当转换结果类型为GeometryCollection时,这些条件适用:
-
GeometryCollection和GeomCollection是同一个结果类型的同义词。 -
如果要转换的表达式是一个良好几何体类型为
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节,“算术运算符”)。要覆盖这个规则,可以使用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_DATESQL 模式时产生警告。 -
对于整数减法,如果启用了
NO_UNSIGNED_SUBTRACTIONSQL 模式,结果即使其中任何操作数是无符号的,也会是有符号的。