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  /  Miscellaneous Functions

14.23 杂项函数

表 14.33 杂项函数

Name Description
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() 定义插入时使用的值

  • ANY_VALUE(arg)

    该函数对于 GROUP BY 查询非常有用,当 ONLY_FULL_GROUP_BY SQL 模式启用时,用于处理 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 列中,也不依赖于它们。因此,address 的值在每个 name 组中是非确定性的。有多种方法可以使 MySQL 接受查询:

    • 将表修改为使 name 成为主键或唯一的 NOT NULL 列。这使 MySQL 能够确定 address 是由 name 唯一确定的;也就是说,addressname 唯一确定。(这种技术不可应用于 NULL 必须作为有效的 name 值。)

    • 使用 ANY_VALUE() 引用 address

      SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;

      在这种情况下,MySQL 忽视 address 值在每个 name 组中的非确定性,并接受查询。这可能有用,如果您只是不关心非聚合列的值是如何选择的。ANY_VALUE() 不是一个聚合函数,类似于 SUM()COUNT()。它只是抑制非确定性测试。

    • 禁用 ONLY_FULL_GROUP_BY。这相当于使用 ANY_VALUE()ONLY_FULL_GROUP_BY 启用,如前一项所述。

    ANY_VALUE() 也有用,如果存在列之间的函数依赖关系,但 MySQL 无法确定它。以下查询是有效的,因为 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;

    ANY_VALUE() 可用于不带 GROUP BY 子句的聚合函数查询:

    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 Handling of 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 参数为 NULL,则返回值为 NULL。如果任何参数无效,将发生错误。

    BIN_TO_UUID() 接受一个或两个参数:

    • 一个参数形式接受二进制 UUID 值。UUID 值假定没有时间低位和时间高位部分交换。字符串结果与二进制参数的顺序相同。

    • 两个参数形式接受二进制 UUID 值和交换标志值:

      • 如果 swap_flag 为 0,两个参数形式等同于一个参数形式。字符串结果与二进制参数的顺序相同。

      • 如果 swap_flag 为 1,UUID 值假定其时间低位和时间高位部分交换。这些部分将在结果值中恢复到原始位置。

    有关使用示例和时间部分交换信息,请参阅 UUID_TO_BIN() 函数描述。

  • DEFAULT(col_name)

    返回表列的默认值。如果列没有默认值,将发生错误。

    使用 DEFAULT(col_name) 指定命名列的默认值仅适用于具有文字默认值的列,而不适用于具有表达式默认值的列。

    mysql> UPDATE t SET i = DEFAULT(i)+1 WHERE id < 100;
  • FORMAT(X,D)

    将数字 X 格式化为类似 '#,###,###.##' 的格式,四舍五入到 D 小数位,并将结果作为字符串返回。有关详细信息,请参阅 第 14.8 节,“字符串函数和操作符”

  • GROUPING(expr [, expr] ...)

    对于包含 WITH ROLLUP 修饰符的 GROUP BY 查询,ROLLUP 操作生成超聚合输出行,其中 NULL 代表所有值的集合。GROUPING() 函数使您可以区分超聚合行中的 NULL 值和常规分组行中的 NULL 值。

    GROUPING() 可以在选择列表、HAVING 子句和 ORDER BY 子句中使用。

    每个 GROUPING() 的参数必须是 GROUP BY 子句中的表达式的精确匹配。表达式不能是位置规格符。对于每个表达式,GROUPING() 生成 1,如果当前行的表达式值是超聚合值的 NULL。否则,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 值和常规分组行中的 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
    • GROUP BY 字面量表达式不应该在 HAVING 子句中使用作为 GROUPING() 参数。由于优化器对 GROUP BYHAVING 的评估顺序不同,匹配可能会成功,但 GROUPING() 评估不会产生预期的结果。考虑以下查询:

      SELECT a AS f1, 'w' AS f2
      FROM t
      GROUP BY f1, f2 WITH ROLLUP
      HAVING GROUPING(f2) = 1;

      GROUPING() 在 literal 常量表达式中比 HAVING 子句更早地被评估,并返回 0。要检查这种查询是否受到影响,请使用 EXPLAIN 并在 Extra 列中查找 Impossible having

    有关 WITH ROLLUPGROUPING() 的更多信息,请参阅 第 14.19.2 节,“GROUP BY 修饰符”

  • INET_ATON(expr)

    给定 IPv4 网络地址的点分四进制表示形式字符串,返回一个整数,该整数表示地址的网络字节顺序(大端)值。INET_ATON() 如果不理解其参数,或者如果 exprNULL,则返回 NULL

    mysql> SELECT INET_ATON('10.0.5.9');
            -> 167773449

    例如,返回值计算为 10×2563 + 0×2562 + 5×256 + 9。

    INET_ATON() 可能或不返回非 NULL 结果对于短形式 IP 地址(例如 '127.1' 作为 '127.0.0.1' 的表示形式)。因此,不应使用 INET_ATON() 对于这种地址。

    Note

    要存储由 INET_ATON() 生成的值,请使用 INT UNSIGNED 列而不是 INT,因为后者是有符号的。如果使用有符号列,无法正确存储对应于 IP 地址的值,其中第一八位大于 127。请参阅 第 13.1.7 节,“超出范围和溢出处理”

  • INET_NTOA(expr)

    给定网络字节顺序的 IPv4 网络地址的数字值,返回地址的点分四进制字符串表示形式。INET_NTOA() 如果不理解其参数,则返回 NULL

    mysql> SELECT INET_NTOA(167773449);
            -> '10.0.5.9'
  • INET6_ATON(expr)

    给定 IPv6 或 IPv4 网络地址的字符串,返回一个二进制字符串,该字符串表示地址的网络字节顺序(大端)值。由于数字格式 IPv6 地址需要更多字节 than 最大整数类型,因此该函数返回的表示形式具有 VARBINARY 数据类型:VARBINARY(16) 用于 IPv6 地址和 VARBINARY(4) 用于 IPv4 地址。如果参数不是有效的地址,或者如果它是 NULLINET6_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%1fe80::3%eth0

    • 不允许尾随网络掩码,如 2001:45f:3:ba::/64198.51.100.0/24

    • 对于表示 IPv4 地址的值,只支持无类地址。类地址,如 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 约束也适用于 IPv6 地址,其中包含 IPv4 地址部分,如 IPv4 兼容或 IPv4 映射地址。

    要将 IPv4 地址 expr 从数字形式转换为 IPv6 地址,从而将其表示为 INT 值转换为 VARBINARY 值,请使用以下表达式:

    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 命令行客户端”

  • INET6_NTOA(expr)

    给定一个 IPv6 或 IPv4 网络地址,以二进制字符串形式表示,返回该地址的字符串表示形式,以连接字符集形式返回。如果参数无效或为空,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 命令行客户端”

  • IS_IPV4(expr)

    如果参数是一个有效的 IPv4 地址字符串,返回 1,否则返回 0。如果 expr为空,返回 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。反之则不然:在某些情况下,INET_ATON() 返回非 NULL 时,IS_IPV4() 返回 0。

    正如前面的备注所示,IS_IPV4()INET_ATON() 更严格地检查有效的 IPv4 地址,因此它可能对需要对无效值进行强检查的应用程序很有用。或者,使用 INET6_ATON() 将 IPv4 地址转换为内部形式,并检查结果是否为 NULL(这表明无效地址)。INET6_ATON()IS_IPV4() 一样严格地检查 IPv4 地址。

  • IS_IPV4_COMPAT(expr)

    该函数将 IPv6 地址表示为数字字符串形式,作为 INET6_ATON() 的返回值。它返回 1 如果参数是有效的 IPv4 兼容 IPv6 地址,否则返回 0(除非 exprNULL,在这种情况下该函数返回 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 部分也可以使用十六进制表示法。例如,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
  • IS_IPV4_MAPPED(expr)

    该函数将 IPv6 地址表示为数字字符串形式,作为 INET6_ATON() 的返回值。它返回 1 如果参数是有效的 IPv4 映射 IPv6 地址,否则返回 0,除非 exprNULL,在这种情况下该函数返回 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 部分也可以使用十六进制表示法:

    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
  • IS_IPV6(expr)

    如果参数是有效的 IPv6 地址字符串,返回 1,否则返回 0,除非 exprNULL,在这种情况下该函数返回 NULL。该函数不认为 IPv4 地址是有效的 IPv6 地址。

    mysql> SELECT IS_IPV6('10.0.5.9'), IS_IPV6('::1');
            -> 0, 1

    对于给定的参数,如果 IS_IPV6() 返回 1,INET6_ATON() 返回非 NULL

  • IS_UUID(string_uuid)

    如果参数是有效的字符串格式 UUID,返回 1,否则返回 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(name,value)

    返回给定的值。当用于生成结果集列时,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 语句”,以获取更多关于列别名的信息。

  • SLEEP(duration)

    休眠(暂停)指定的秒数,然后返回 0。duration 可以有小数部分。如果参数为 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,则会记录警告。

  • UUID()

    返回根据 RFC 4122 生成的通用唯一标识符(UUID),通用唯一标识符(UUID)URN 命名空间 (http://www.ietf.org/rfc/rfc4122.txt)。

    UUID 设计为在空间和时间上全球唯一的标识符。两个 UUID() 调用将生成两个不同的值,即使这些调用是在两个不相连的设备上执行的。

    Warning

    虽然 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 值,请使用 UUID_TO_BIN()BIN_TO_UUID() 函数。要检查字符串是否为有效的 UUID 值,请使用 IS_UUID() 函数。

    此函数对于基于语句的复制是不安全的。如果您在binlog_format设置为STATEMENT时使用该函数,将记录警告。

  • UUID_SHORT()

    返回一个“短”通用标识符作为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
    Note

    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()函数生成的值。对于通过其他方式生成的UUID值,时间部分交换不提供任何好处。有关版本1格式的详细信息,请参阅UUID()函数描述。

    假设您有以下字符串UUID值:

    mysql> SET @uuid = '6ccd780c-baba-1026-9564-5b8c656024db';

    要将字符串UUID转换为二进制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()将时间部分交换,应该也将第二个参数传递给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 |
    +--------------------------------------+

    如果从 UUID_TO_BIN()mysql 客户端内部调用,二进制字符串将以十六进制表示法显示,取决于 --binary-as-hex 选项的值。有关该选项的更多信息,请参阅 第 6.5.1 节,“mysql — MySQL 命令行客户端”

  • VALUES(col_name)

    INSERT ... ON DUPLICATE KEY UPDATE 语句中,可以在 UPDATE 子句中使用 VALUES(col_name) 函数来引用 INSERT 部分的列值。换言之,VALUES(col_name)UPDATE 子句中引用的是,如果没有重复键冲突发生,col_name 将被插入的值。该函数在多行插入中非常有用。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);
    Important

    这种用法已弃用,并将在未来 MySQL 版本中删除。请改用行别名或行和列别名。有关更多信息和示例,请参阅 第 15.2.7.2 节,“INSERT ... ON DUPLICATE KEY UPDATE 语句”