表 14.33 其他函数
名称 | 说明 |
---|---|
ANY_VALUE() |
抑制 ONLY_FULL_GROUP_BY 值拒绝 |
BIN_TO_UUID() |
将二进制 UUID 转换为字符串 |
DEFAULT() |
返回表列的默认值 |
GROUPING() |
区分超级聚合 ROLLUP 行和常规行 |
INET_ATON() |
返回 IP 地址的数值 |
INET_NTOA() |
从数值返回 IP 地址 |
IS_UUID() |
参数是否为有效的 UUID |
NAME_CONST() |
使列具有给定的名称 |
SLEEP() |
休眠几秒钟 |
UUID() |
返回通用唯一标识符 (UUID) |
UUID_SHORT() |
返回一个整数值的通用唯一标识符 |
UUID_TO_BIN() |
将字符串 UUID 转换为二进制 |
VALUES() |
定义在 INSERT 期间要使用的值 |
当
ONLY_FULL_GROUP_BY
SQL 模式启用时,此函数对于GROUP BY
查询非常有用,适用于 MySQL 由于无法确定的原因拒绝您知道有效的查询的情况。 函数返回值和类型与其参数的返回值和类型相同,但不会针对ONLY_FULL_GROUP_BY
SQL 模式检查函数结果。例如,如果
name
是一个未索引的列,则以下查询在启用了ONLY_FULL_GROUP_BY
的情况下会失败mysql> SELECT name, address, MAX(age) FROM t GROUP BY name; ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'mydb.t.address' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
发生故障是因为
address
是一个非聚合列,它既没有在GROUP BY
列中命名,也不在函数上依赖于它们。 因此,每个name
组中行的address
值是不确定的。 有多种方法可以让 MySQL 接受查询更改表以使
name
成为主键或唯一的NOT NULL
列。 这使得 MySQL 能够确定address
在函数上依赖于name
;也就是说,address
由name
唯一确定。 (如果NULL
必须被允许作为有效的name
值,则此技术不适用。)使用
ANY_VALUE()
来引用address
SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;
在这种情况下,MySQL 会忽略每个
name
组中address
值的不确定性,并接受查询。 如果您只是不关心为每个组选择哪个非聚合列的值,这可能会很有用。ANY_VALUE()
不是聚合函数,这与SUM()
或COUNT()
等函数不同。 它只是起到抑制不确定性测试的作用。禁用
ONLY_FULL_GROUP_BY
。 这相当于在启用了ONLY_FULL_GROUP_BY
的情况下使用ANY_VALUE()
,如上一项所述。
如果列之间存在函数依赖关系,但 MySQL 无法确定它,则
ANY_VALUE()
也很有用。 以下查询有效,因为age
在函数上依赖于分组列age-1
,但 MySQL 无法识别这一点,并在启用了ONLY_FULL_GROUP_BY
的情况下拒绝查询SELECT age FROM t GROUP BY age-1;
要使 MySQL 接受查询,请使用
ANY_VALUE()
SELECT ANY_VALUE(age) FROM t GROUP BY age-1;
对于在没有
GROUP BY
子句的情况下引用聚合函数的查询,可以使用ANY_VALUE()
mysql> SELECT name, MAX(age) FROM t; ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'mydb.t.name'; this is incompatible with sql_mode=only_full_group_by
如果没有
GROUP BY
,则只有一个组,并且为该组选择哪个name
值是不确定的。ANY_VALUE()
告诉 MySQL 接受查询SELECT ANY_VALUE(name), MAX(age) FROM t;
可能是由于给定数据集的某些属性,您知道所选的非聚合列实际上在函数上依赖于
GROUP BY
列。 例如,应用程序可以对一个列相对于另一个列强制实施唯一性。 在这种情况下,对实际上在函数上依赖的列使用ANY_VALUE()
可能是有意义的。有关其他讨论,请参阅 第 14.19.3 节,“MySQL 对 GROUP BY 的处理”。
BIN_TO_UUID(
,binary_uuid
)BIN_TO_UUID(
binary_uuid
,swap_flag
)BIN_TO_UUID()
是UUID_TO_BIN()
的逆函数。 它将二进制 UUID 转换为字符串 UUID 并返回结果。 二进制值应该是作为VARBINARY(16)
值的 UUID。 返回值是一个由破折号分隔的五个十六进制数字的字符串。 (有关此格式的详细信息,请参阅UUID()
函数说明。)如果 UUID 参数为NULL
,则返回值为NULL
。 如果任何参数无效,则会发生错误。BIN_TO_UUID()
接受一个或两个参数单参数形式采用二进制 UUID 值。假定 UUID 值的 time-low 和 time-high 部分未交换。字符串结果与二进制参数的顺序相同。
双参数形式采用二进制 UUID 值和一个交换标志值。
如果
swap_flag
为 0,则双参数形式等效于单参数形式。字符串结果与二进制参数的顺序相同。如果
swap_flag
为 1,则假定 UUID 值的 time-low 和 time-high 部分已交换。在结果值中,这些部分将交换回其原始位置。
有关使用示例和时间部分交换的信息,请参阅
UUID_TO_BIN()
函数描述。返回表列的默认值。如果该列没有默认值,则会导致错误。
仅当列具有字面默认值时,才允许使用
DEFAULT(
指定命名列的默认值,而对于具有表达式默认值的列则不允许。col_name
)mysql> UPDATE t SET i = DEFAULT(i)+1 WHERE id < 100;
将数字
X
格式化为类似'#,###,###.##'
的格式,四舍五入到D
位小数,并将结果作为字符串返回。有关详细信息,请参阅 第 14.8 节,“字符串函数和运算符”。对于包含
WITH ROLLUP
修饰符的GROUP BY
查询,ROLLUP
操作会生成超级聚合输出行,其中NULL
表示所有值的集合。GROUPING()
函数使您能够区分超级聚合行中的NULL
值和常规分组行中的NULL
值。GROUPING()
允许在选择列表、HAVING
子句和ORDER BY
子句中使用。GROUPING()
的每个参数都必须是与GROUP BY
子句中的表达式完全匹配的表达式。该表达式不能是位置说明符。对于每个表达式,如果当前行中的表达式值为表示超级聚合值的NULL
,则GROUPING()
生成 1。否则,GROUPING()
生成 0,表示表达式值是常规结果行的NULL
或不是NULL
。假设表
t1
包含以下行,其中NULL
表示类似于““其他” 或““未知””的内容:mysql> SELECT * FROM t1; +------+-------+----------+ | name | size | quantity | +------+-------+----------+ | ball | small | 10 | | ball | large | 20 | | ball | NULL | 5 | | hoop | small | 15 | | hoop | large | 5 | | hoop | NULL | 3 | +------+-------+----------+
不带
WITH ROLLUP
的表汇总如下所示:mysql> SELECT name, size, SUM(quantity) AS quantity FROM t1 GROUP BY name, size; +------+-------+----------+ | name | size | quantity | +------+-------+----------+ | ball | small | 10 | | ball | large | 20 | | ball | NULL | 5 | | hoop | small | 15 | | hoop | large | 5 | | hoop | NULL | 3 | +------+-------+----------+
结果包含
NULL
值,但这些值不代表超级聚合行,因为查询不包含WITH ROLLUP
。添加
WITH ROLLUP
会生成包含其他NULL
值的超级聚合汇总行。但是,如果不同时将此结果与前一个结果进行比较,则很难看出哪些NULL
值出现在超级聚合行中,哪些值出现在常规分组行中:mysql> SELECT name, size, SUM(quantity) AS quantity FROM t1 GROUP BY name, size WITH ROLLUP; +------+-------+----------+ | name | size | quantity | +------+-------+----------+ | ball | NULL | 5 | | ball | large | 20 | | ball | small | 10 | | ball | NULL | 35 | | hoop | NULL | 3 | | hoop | large | 5 | | hoop | small | 15 | | hoop | NULL | 23 | | NULL | NULL | 58 | +------+-------+----------+
要区分超级聚合行中的
NULL
值和常规分组行中的NULL
值,请使用GROUPING()
,它仅对超级聚合NULL
值返回 1:mysql> SELECT name, size, SUM(quantity) AS quantity, GROUPING(name) AS grp_name, GROUPING(size) AS grp_size FROM t1 GROUP BY name, size WITH ROLLUP; +------+-------+----------+----------+----------+ | name | size | quantity | grp_name | grp_size | +------+-------+----------+----------+----------+ | ball | NULL | 5 | 0 | 0 | | ball | large | 20 | 0 | 0 | | ball | small | 10 | 0 | 0 | | ball | NULL | 35 | 0 | 1 | | hoop | NULL | 3 | 0 | 0 | | hoop | large | 5 | 0 | 0 | | hoop | small | 15 | 0 | 0 | | hoop | NULL | 23 | 0 | 1 | | NULL | NULL | 58 | 1 | 1 | +------+-------+----------+----------+----------+
GROUPING()
的常见用法:为超级聚合
NULL
值替换标签:mysql> SELECT IF(GROUPING(name) = 1, 'All items', name) AS name, IF(GROUPING(size) = 1, 'All sizes', size) AS size, SUM(quantity) AS quantity FROM t1 GROUP BY name, size WITH ROLLUP; +-----------+-----------+----------+ | name | size | quantity | +-----------+-----------+----------+ | ball | NULL | 5 | | ball | large | 20 | | ball | small | 10 | | ball | All sizes | 35 | | hoop | NULL | 3 | | hoop | large | 5 | | hoop | small | 15 | | hoop | All sizes | 23 | | All items | All sizes | 58 | +-----------+-----------+----------+
通过过滤掉常规分组行来仅返回超级聚合行:
mysql> SELECT name, size, SUM(quantity) AS quantity FROM t1 GROUP BY name, size WITH ROLLUP HAVING GROUPING(name) = 1 OR GROUPING(size) = 1; +------+------+----------+ | name | size | quantity | +------+------+----------+ | ball | NULL | 35 | | hoop | NULL | 23 | | NULL | NULL | 58 | +------+------+----------+
GROUPING()
允许使用多个表达式参数。在这种情况下,GROUPING()
返回值表示由每个表达式的结果组合而成的位掩码,其中最低有效位对应于最右边表达式的结果。例如,对于三个表达式参数,GROUPING(
的计算方式如下:expr1
,expr2
,expr3
)result for GROUPING(expr3) + result for GROUPING(expr2) << 1 + result for GROUPING(expr1) << 2
以下查询显示了单个参数的
GROUPING()
结果如何组合为对多个参数的调用以生成位掩码值:mysql> SELECT name, size, SUM(quantity) AS quantity, GROUPING(name) AS grp_name, GROUPING(size) AS grp_size, GROUPING(name, size) AS grp_all FROM t1 GROUP BY name, size WITH ROLLUP; +------+-------+----------+----------+----------+---------+ | name | size | quantity | grp_name | grp_size | grp_all | +------+-------+----------+----------+----------+---------+ | ball | NULL | 5 | 0 | 0 | 0 | | ball | large | 20 | 0 | 0 | 0 | | ball | small | 10 | 0 | 0 | 0 | | ball | NULL | 35 | 0 | 1 | 1 | | hoop | NULL | 3 | 0 | 0 | 0 | | hoop | large | 5 | 0 | 0 | 0 | | hoop | small | 15 | 0 | 0 | 0 | | hoop | NULL | 23 | 0 | 1 | 1 | | NULL | NULL | 58 | 1 | 1 | 3 | +------+-------+----------+----------+----------+---------+
对于多个表达式参数,如果任何表达式表示超级聚合值,则
GROUPING()
返回值将为非零值。因此,多参数GROUPING()
语法提供了一种更简单的方法来编写前面仅返回超级聚合行的查询,方法是使用单个多参数GROUPING()
调用,而不是多个单参数调用:mysql> SELECT name, size, SUM(quantity) AS quantity FROM t1 GROUP BY name, size WITH ROLLUP HAVING GROUPING(name, size) <> 0; +------+------+----------+ | name | size | quantity | +------+------+----------+ | ball | NULL | 35 | | hoop | NULL | 23 | | NULL | NULL | 58 | +------+------+----------+
GROUPING()
的使用受以下限制:不要使用子查询
GROUP BY
表达式作为GROUPING()
参数,因为匹配可能会失败。例如,此查询的匹配将失败:mysql> SELECT GROUPING((SELECT MAX(name) FROM t1)) FROM t1 GROUP BY (SELECT MAX(name) FROM t1) WITH ROLLUP; ERROR 3580 (HY000): Argument #1 of GROUPING function is not in GROUP BY
不应在
HAVING
子句中将GROUP BY
字面量表达式用作GROUPING()
参数。由于优化器评估GROUP BY
和HAVING
的时间不同,因此匹配可能会成功,但GROUPING()
评估不会产生预期结果。请考虑以下查询:SELECT a AS f1, 'w' AS f2 FROM t GROUP BY f1, f2 WITH ROLLUP HAVING GROUPING(f2) = 1;
对于字面量常量表达式,
GROUPING()
的评估时间比整个HAVING
子句要早,并且返回 0。要检查此类查询是否受影响,请使用EXPLAIN
并在Extra
列中查找Impossible having
。
有关
WITH ROLLUP
和GROUPING()
的更多信息,请参阅 第 14.19.2 节,“GROUP BY 修饰符”。给定 IPv4 网络地址的点分四段表示形式作为字符串,返回一个整数,该整数表示地址的数值,采用网络字节顺序(大端序)。如果
INET_ATON()
无法理解其参数,或者expr
为NULL
,则返回NULL
。mysql> SELECT INET_ATON('10.0.5.9'); -> 167773449
对于此示例,返回值计算为 10×2563 + 0×2562 + 5×256 + 9。
对于简写形式的 IP 地址(例如将
'127.1'
表示为'127.0.0.1'
),INET_ATON()
可能会返回非NULL
结果,也可能不会。因此,不应将INET_ATON()
a 用于此类地址。注意要存储由
INET_ATON()
生成的值,请使用INT UNSIGNED
列,而不是有符号的INT
。如果使用有符号列,则无法正确存储第一个八位字节大于 127 的 IP 地址对应的值。请参阅 第 13.1.7 节,“超出范围和溢出处理”。给定采用网络字节顺序的数字 IPv4 网络地址,返回该地址的点分四段字符串表示形式,采用连接字符集中的字符串形式。如果
INET_NTOA()
无法理解其参数,则返回NULL
。mysql> SELECT INET_NTOA(167773449); -> '10.0.5.9'
给定 IPv6 或 IPv4 网络地址作为字符串,返回一个二进制字符串,该字符串表示地址的数值,采用网络字节顺序(大端序)。由于数字格式的 IPv6 地址需要的字节数超过了最大的整数类型,因此此函数返回的表示形式具有
VARBINARY
数据类型:IPv6 地址为VARBINARY(16)
,IPv4 地址为VARBINARY(4)
。如果参数不是有效的地址,或者为NULL
,则INET6_ATON()
返回NULL
。以下示例使用
HEX()
以可打印形式显示INET6_ATON()
结果:mysql> SELECT HEX(INET6_ATON('fdfe::5a55:caff:fefa:9089')); -> 'FDFE0000000000005A55CAFFFEFA9089' mysql> SELECT HEX(INET6_ATON('10.0.5.9')); -> '0A000509'
INET6_ATON()
对有效参数遵循若干约束。这些约束与示例一起列在下面的列表中。不允许使用尾随区域 ID,如
fe80::3%1
或fe80::3%eth0
中所示。不允许使用尾随网络掩码,如
2001:45f:3:ba::/64
或198.51.100.0/24
中所示。对于表示 IPv4 地址的值,仅支持无类地址。将拒绝类ful 地址,例如
198.51.1
。不允许使用尾随端口号,如198.51.100.2:8080
中所示。不允许在地址组件中使用十六进制数,如198.0xa0.1.2
中所示。不支持八进制数:198.51.010.1
被视为198.51.10.1
,而不是198.51.8.1
。这些 IPv4 约束也适用于具有 IPv4 地址部分的 IPv6 地址,例如 IPv4 兼容地址或 IPv4 映射地址。
要将以数字形式表示为
INT
值的 IPv4 地址expr
转换为以数字形式表示为VARBINARY
值的 IPv6 地址,请使用以下表达式:INET6_ATON(INET_NTOA(expr))
例如:
mysql> SELECT HEX(INET6_ATON(INET_NTOA(167773449))); -> '0A000509'
如果从 mysql 客户端内部调用
INET6_ATON()
,则二进制字符串将使用十六进制表示法显示,具体取决于--binary-as-hex
的值。有关该选项的更多信息,请参阅 第 6.5.1 节,“mysql — MySQL 命令行客户端”。给定以数字形式表示为二进制字符串的 IPv6 或 IPv4 网络地址,返回该地址的字符串表示形式,采用连接字符集中的字符串形式。如果参数不是有效的地址,或者为
NULL
,则INET6_NTOA()
返回NULL
。INET6_NTOA()
具有以下属性:它不使用操作系统函数来执行转换,因此输出字符串与平台无关。
返回字符串的最大长度为 39(4 x 8 + 7)。给定以下语句:
CREATE TABLE t AS SELECT INET6_NTOA(expr) AS c1;
结果表将具有以下定义:
CREATE TABLE t (c1 VARCHAR(39) CHARACTER SET utf8mb3 DEFAULT NULL);
返回字符串对 IPv6 地址使用小写字母。
mysql> SELECT INET6_NTOA(INET6_ATON('fdfe::5a55:caff:fefa:9089')); -> 'fdfe::5a55:caff:fefa:9089' mysql> SELECT INET6_NTOA(INET6_ATON('10.0.5.9')); -> '10.0.5.9' mysql> SELECT INET6_NTOA(UNHEX('FDFE0000000000005A55CAFFFEFA9089')); -> 'fdfe::5a55:caff:fefa:9089' mysql> SELECT INET6_NTOA(UNHEX('0A000509')); -> '10.0.5.9'
如果从 mysql 客户端内部调用
INET6_NTOA()
,则二进制字符串会根据--binary-as-hex
的值使用十六进制表示法显示。有关该选项的更多信息,请参见第 6.5.1 节,“mysql — MySQL 命令行客户端”。如果参数是指定为字符串的有效 IPv4 地址,则返回 1,否则返回 0。如果
expr
为NULL
,则返回NULL
。mysql> SELECT IS_IPV4('10.0.5.9'), IS_IPV4('10.0.5.256'); -> 1, 0
对于给定参数,如果
IS_IPV4()
返回 1,则INET_ATON()
(和INET6_ATON()
)返回非NULL
。反之则不成立:在某些情况下,当IS_IPV4()
返回 0 时,INET_ATON()
会返回非NULL
。正如前面的说明所暗示的,
IS_IPV4()
比INET_ATON()
对构成有效 IPv4 地址的要求更严格,因此它可能对需要对无效值执行严格检查的应用程序很有用。或者,使用INET6_ATON()
将 IPv4 地址转换为内部格式并检查结果是否为NULL
(这表示地址无效)。INET6_ATON()
在检查 IPv4 地址方面与IS_IPV4()
一样严格。此函数采用以数字形式表示的 IPv6 地址作为二进制字符串,如
INET6_ATON()
返回的那样。如果参数是有效的 IPv4 兼容 IPv6 地址,则返回 1,否则返回 0(除非expr
为NULL
,在这种情况下,函数返回NULL
)。IPv4 兼容地址的形式为::
。ipv4_address
mysql> SELECT IS_IPV4_COMPAT(INET6_ATON('::10.0.5.9')); -> 1 mysql> SELECT IS_IPV4_COMPAT(INET6_ATON('::ffff:10.0.5.9')); -> 0
IPv4 兼容地址的 IPv4 部分也可以使用十六进制表示法表示。例如,
198.51.100.1
具有以下原始十六进制值mysql> SELECT HEX(INET6_ATON('198.51.100.1')); -> 'C6336401'
以 IPv4 兼容形式表示,
::198.51.100.1
等效于::c0a8:0001
或(不带前导零)::c0a8:1
mysql> SELECT -> IS_IPV4_COMPAT(INET6_ATON('::198.51.100.1')), -> IS_IPV4_COMPAT(INET6_ATON('::c0a8:0001')), -> IS_IPV4_COMPAT(INET6_ATON('::c0a8:1')); -> 1, 1, 1
此函数采用以数字形式表示的 IPv6 地址作为二进制字符串,如
INET6_ATON()
返回的那样。如果参数是有效的 IPv4 映射 IPv6 地址,则返回 1,否则返回 0,除非expr
为NULL
,在这种情况下,函数返回NULL
。IPv4 映射地址的形式为::ffff:
。ipv4_address
mysql> SELECT IS_IPV4_MAPPED(INET6_ATON('::10.0.5.9')); -> 0 mysql> SELECT IS_IPV4_MAPPED(INET6_ATON('::ffff:10.0.5.9')); -> 1
与
IS_IPV4_COMPAT()
一样,IPv4 映射地址的 IPv4 部分也可以使用十六进制表示法表示mysql> SELECT -> IS_IPV4_MAPPED(INET6_ATON('::ffff:198.51.100.1')), -> IS_IPV4_MAPPED(INET6_ATON('::ffff:c0a8:0001')), -> IS_IPV4_MAPPED(INET6_ATON('::ffff:c0a8:1')); -> 1, 1, 1
如果参数是指定为字符串的有效 IPv6 地址,则返回 1,否则返回 0,除非
expr
为NULL
,在这种情况下,函数返回NULL
。此函数不将 IPv4 地址视为有效的 IPv6 地址。mysql> SELECT IS_IPV6('10.0.5.9'), IS_IPV6('::1'); -> 0, 1
对于给定参数,如果
IS_IPV6()
返回 1,则INET6_ATON()
返回非NULL
。如果参数是有效的字符串格式 UUID,则返回 1,如果参数不是有效的 UUID,则返回 0,如果参数是
NULL
,则返回NULL
。“有效” 表示该值采用可以解析的格式。也就是说,它具有正确的长度并且仅包含允许的字符(任何字母大小写的十六进制数字,以及可选的破折号和大括号)。此格式是最常见的
aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
还允许使用以下其他格式
aaaaaaaabbbbccccddddeeeeeeeeeeee {aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee}
有关值中字段的含义,请参见
UUID()
函数说明。mysql> SELECT IS_UUID('6ccd780c-baba-1026-9564-5b8c656024db'); +-------------------------------------------------+ | IS_UUID('6ccd780c-baba-1026-9564-5b8c656024db') | +-------------------------------------------------+ | 1 | +-------------------------------------------------+ mysql> SELECT IS_UUID('6CCD780C-BABA-1026-9564-5B8C656024DB'); +-------------------------------------------------+ | IS_UUID('6CCD780C-BABA-1026-9564-5B8C656024DB') | +-------------------------------------------------+ | 1 | +-------------------------------------------------+ mysql> SELECT IS_UUID('6ccd780cbaba102695645b8c656024db'); +---------------------------------------------+ | IS_UUID('6ccd780cbaba102695645b8c656024db') | +---------------------------------------------+ | 1 | +---------------------------------------------+ mysql> SELECT IS_UUID('{6ccd780c-baba-1026-9564-5b8c656024db}'); +---------------------------------------------------+ | IS_UUID('{6ccd780c-baba-1026-9564-5b8c656024db}') | +---------------------------------------------------+ | 1 | +---------------------------------------------------+ mysql> SELECT IS_UUID('6ccd780c-baba-1026-9564-5b8c6560'); +---------------------------------------------+ | IS_UUID('6ccd780c-baba-1026-9564-5b8c6560') | +---------------------------------------------+ | 0 | +---------------------------------------------+ mysql> SELECT IS_UUID(RAND()); +-----------------+ | IS_UUID(RAND()) | +-----------------+ | 0 | +-----------------+
返回给定的值。当用于生成结果集列时,
NAME_CONST()
会使该列具有给定的名称。参数应该是常量。mysql> SELECT NAME_CONST('myname', 14); +--------+ | myname | +--------+ | 14 | +--------+
此函数仅供内部使用。当服务器从包含对本地程序变量引用的存储程序写入语句时,它会使用此函数,如第 27.7 节,“存储程序二进制日志记录” 中所述。您可能会在 mysqlbinlog 的输出中看到此函数。
对于您的应用程序,您可以使用简单的别名来获得与上面示例中完全相同的结果,如下所示
mysql> SELECT 14 AS myname; +--------+ | myname | +--------+ | 14 | +--------+ 1 row in set (0.00 sec)
有关列别名的更多信息,请参见第 15.2.13 节,“SELECT 语句”。
休眠(暂停)
duration
参数给定的秒数,然后返回 0。持续时间可以包含小数部分。如果参数为NULL
或负数,则SLEEP()
会生成警告,或者在严格 SQL 模式下生成错误。当 sleep 正常返回(没有中断)时,它返回 0
mysql> SELECT SLEEP(1000); +-------------+ | SLEEP(1000) | +-------------+ | 0 | +-------------+
当
SLEEP()
是被中断的查询调用的唯一内容时,它返回 1 并且查询本身不返回错误。无论查询是被终止还是超时,都是如此此语句使用来自另一个会话的
KILL QUERY
中断mysql> SELECT SLEEP(1000); +-------------+ | SLEEP(1000) | +-------------+ | 1 | +-------------+
此语句因超时而中断
mysql> SELECT /*+ MAX_EXECUTION_TIME(1) */ SLEEP(1000); +-------------+ | SLEEP(1000) | +-------------+ | 1 | +-------------+
当
SLEEP()
只是被中断的查询的一部分时,查询会返回错误此语句使用来自另一个会话的
KILL QUERY
中断mysql> SELECT 1 FROM t1 WHERE SLEEP(1000); ERROR 1317 (70100): Query execution was interrupted
此语句因超时而中断
mysql> SELECT /*+ MAX_EXECUTION_TIME(1000) */ 1 FROM t1 WHERE SLEEP(1000); ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded
此函数对于基于语句的复制不安全。如果在
binlog_format
设置为STATEMENT
时使用此函数,则会记录警告。返回根据 RFC 4122 生成的通用唯一标识符 (UUID),“通用唯一标识符 (UUID) URN 命名空间” (http://www.ietf.org/rfc/rfc4122.txt)。
UUID 的设计目标是在空间和时间上全局唯一的数字。两次调用
UUID()
预计会生成两个不同的值,即使这些调用是在彼此不相连接的两台独立设备上执行的。警告尽管
UUID()
值旨在唯一,但它们不一定不可猜测或不可预测。如果需要不可预测性,则应以其他方式生成 UUID 值。UUID()
返回的值符合 RFC 4122 中描述的 UUID 版本 1。该值是一个 128 位数字,表示为utf8mb3
字符串,包含五个十六进制数字,格式为aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
前三个数字由时间戳的低位、中间位和高位部分生成。高位部分还包括 UUID 版本号。
第四个数字保留时间唯一性,以防时间戳值失去单调性(例如,由于夏令时)。
第五个数字是 IEEE 802 节点号,它提供空间唯一性。如果后者不可用(例如,因为主机设备没有以太网卡,或者不知道如何在主机操作系统上找到接口的硬件地址),则使用随机数代替。在这种情况下,不能保证空间唯一性。但是,冲突的概率应该非常低。
仅在 FreeBSD、Linux 和 Windows 上才会考虑接口的 MAC 地址。在其他操作系统上,MySQL 使用随机生成的 48 位数字。
mysql> SELECT UUID(); -> '6ccd780c-baba-1026-9564-5b8c656024db'
要在字符串和二进制 UUID 值之间进行转换,请使用
UUID_TO_BIN()
和BIN_TO_UUID()
函数。要检查字符串是否是有效的 UUID 值,请使用IS_UUID()
函数。此函数对于基于语句的复制不安全。如果在
binlog_format
设置为STATEMENT
时使用此函数,则会记录警告。返回一个““短””通用标识符,作为 64 位无符号整数。
UUID_SHORT()
返回的值与UUID()
函数返回的字符串格式的 128 位标识符不同,并且具有不同的唯一性属性。如果满足以下条件,则保证UUID_SHORT()
的值为唯一值当前服务器的
server_id
值介于 0 到 255 之间,并且在您的源服务器和副本服务器集中是唯一的您没有在 mysqld 重新启动之间回退服务器主机的系统时间
您在 mysqld 重新启动之间平均每秒调用
UUID_SHORT()
的次数少于 1600 万次
UUID_SHORT()
返回值是这样构造的(server_id & 255) << 56 + (server_startup_time_in_seconds << 24) + incremented_variable++;
mysql> SELECT UUID_SHORT(); -> 92395783831158784
注意UUID_SHORT()
不适用于基于语句的复制。UUID_TO_BIN(
,string_uuid
)UUID_TO_BIN(
string_uuid
,swap_flag
)将字符串 UUID 转换为二进制 UUID 并返回结果。(
IS_UUID()
函数说明列出了允许的字符串 UUID 格式。)返回的二进制 UUID 是VARBINARY(16)
值。如果 UUID 参数为NULL
,则返回值为NULL
。如果任何参数无效,则会发生错误。UUID_TO_BIN()
接受一个或两个参数单参数形式采用字符串 UUID 值。二进制结果的顺序与字符串参数的顺序相同。
双参数形式采用字符串 UUID 值和标志值
如果
swap_flag
为 0,则双参数形式等效于单参数形式。二进制结果的顺序与字符串参数的顺序相同。如果
swap_flag
为 1,则返回值的格式不同:时间低位部分和时间高位部分(分别是第一组和第三组十六进制数字)交换位置。这会将变化更快的部分移到右侧,如果结果存储在索引列中,则可以提高索引效率。
时间部分交换假设使用 UUID 版本 1 值,例如由
UUID()
函数生成的值。 对于由不遵循版本 1 格式的其他方式生成的 UUID 值,时间部分交换没有任何好处。 有关版本 1 格式的详细信息,请参阅UUID()
函数说明。假设您有以下字符串 UUID 值
mysql> SET @uuid = '6ccd780c-baba-1026-9564-5b8c656024db';
要将字符串 UUID 转换为带或不带时间部分交换的二进制,请使用
UUID_TO_BIN()
mysql> SELECT HEX(UUID_TO_BIN(@uuid)); +----------------------------------+ | HEX(UUID_TO_BIN(@uuid)) | +----------------------------------+ | 6CCD780CBABA102695645B8C656024DB | +----------------------------------+ mysql> SELECT HEX(UUID_TO_BIN(@uuid, 0)); +----------------------------------+ | HEX(UUID_TO_BIN(@uuid, 0)) | +----------------------------------+ | 6CCD780CBABA102695645B8C656024DB | +----------------------------------+ mysql> SELECT HEX(UUID_TO_BIN(@uuid, 1)); +----------------------------------+ | HEX(UUID_TO_BIN(@uuid, 1)) | +----------------------------------+ | 1026BABA6CCD780C95645B8C656024DB | +----------------------------------+
要将
UUID_TO_BIN()
返回的二进制 UUID 转换为字符串 UUID,请使用BIN_TO_UUID()
。 如果您通过调用UUID_TO_BIN()
并使用第二个参数 1 来交换时间部分来生成二进制 UUID,则在将二进制 UUID 转换回字符串 UUID 时,您还应将第二个参数 1 传递给BIN_TO_UUID()
以取消交换时间部分mysql> SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid)); +--------------------------------------+ | BIN_TO_UUID(UUID_TO_BIN(@uuid)) | +--------------------------------------+ | 6ccd780c-baba-1026-9564-5b8c656024db | +--------------------------------------+ mysql> SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,0),0); +--------------------------------------+ | BIN_TO_UUID(UUID_TO_BIN(@uuid,0),0) | +--------------------------------------+ | 6ccd780c-baba-1026-9564-5b8c656024db | +--------------------------------------+ mysql> SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,1),1); +--------------------------------------+ | BIN_TO_UUID(UUID_TO_BIN(@uuid,1),1) | +--------------------------------------+ | 6ccd780c-baba-1026-9564-5b8c656024db | +--------------------------------------+
如果在两个方向的转换中使用的时间部分交换不一致,则无法正确恢复原始 UUID
mysql> SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,0),1); +--------------------------------------+ | BIN_TO_UUID(UUID_TO_BIN(@uuid,0),1) | +--------------------------------------+ | baba1026-780c-6ccd-9564-5b8c656024db | +--------------------------------------+ mysql> SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,1),0); +--------------------------------------+ | BIN_TO_UUID(UUID_TO_BIN(@uuid,1),0) | +--------------------------------------+ | 1026baba-6ccd-780c-9564-5b8c656024db | +--------------------------------------+
如果从 mysql 客户端中调用
UUID_TO_BIN()
,则二进制字符串将使用十六进制表示法显示,具体取决于--binary-as-hex
的值。 有关该选项的更多信息,请参阅 第 6.5.1 节,“mysql — MySQL 命令行客户端”。在
INSERT ... ON DUPLICATE KEY UPDATE
语句中,您可以在UPDATE
子句中使用VALUES(
函数来引用语句列名
)INSERT
部分中的列值。 换句话说,UPDATE
子句中的VALUES(
指的是在没有发生重复键冲突的情况下将插入的列名
)列名
的值。 此函数在多行插入中特别有用。VALUES()
函数仅在INSERT
语句的ON DUPLICATE KEY UPDATE
子句中有意义,否则返回NULL
。 请参阅 第 15.2.7.2 节,“INSERT ... ON DUPLICATE KEY UPDATE 语句”。mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) -> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
重要不推荐使用此用法,并且会在未来版本的 MySQL 中删除。 请改用行别名,或行和列别名。 有关更多信息和示例,请参阅 第 15.2.7.2 节,“INSERT ... ON DUPLICATE KEY UPDATE 语句”。