Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 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() 在 INSERT 操作中定义要使用的值

  • ANY_VALUE(arg)

    这个函数在启用了 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中的名称,也不是它们的函数依赖关系。因此,address在每个name组中的值是非确定性的。有多种方法可以使MySQL接受查询:

    • 将表修改为使name成为主键或唯一的NOT NULL列。这使得MySQL能够确定addressname的函数依赖关系,即addressname唯一确定。 (如果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。这等同于使用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处理GROUP BY”

  • BIN_TO_UUID(binary_uuid), BIN_TO_UUID(binary_uuid, swap_flag)

    BIN_TO_UUID()UUID_TO_BIN()的逆运算。它将一个二进制UUID转换为字符串UUID并返回结果。二进制值应该是一个16个字节的VARBINARY值。返回值是一个由五个十六进制数字和分隔符组成的字符串。(关于这个格式的详细信息,请见UUID()函数描述。如果UUID参数是NULL,返回值也是NULL。如果任何参数无效,会出现错误。

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

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

    • 双参数形式将接受一个二进制UUID值和一个swap标志值:

      • 如果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节,“String Functions and Operators”.

  • 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值出现在超级聚合行中,哪些出现在常规分组行中:

    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值,可以使用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() subject to these limitations:

    • 不要将子查询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() 在常量表达式中被评估得更早,在整个HAVING子句中返回 0。要检查是否有查询受到影响,请使用EXPLAIN,并在Extra列中查找Impossible having

    关于WITH ROLLUPGROUPING()的更多信息,请见第14.19.2节,“GROUP BY Modifiers”

  • INET_ATON(expr)

    将 IPv4 网络地址的点分 quad 表示形式作为字符串传递,返回一个整数,该整数表示网络字节顺序(大端)中的地址值。INET_ATON() 如果不理解其参数或exprNULL,则返回NULL

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

    对于这个示例,返回值是通过计算10×2563 + 0×2562 + 5×256 + 9来计算的。

    INET_ATON() 可能会返回短形式IP地址(如'127.1',表示'127.0.0.1')的非NULL结果。由于这个原因,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 网络地址字符串转换为大端字节顺序的二进制字符串。因为 numeric-format IPv6 地址需要更多字节 than the largest integer type,这个函数返回的表示形式使用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()遵守以下有效参数约束。这些约束在下面列表中给出,包括示例。

    • 尾部zone 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约束也适用于具有IPv4地址部分的IPv6地址,如IPv4兼容或IPv4映射地址。

    要将 IPv4 地址expr,以数字形式表示为一个INT值转换为 IPv6 地址,以数字形式表示为一个VARBINARY值,可以使用以下表达式:

    INET6_ATON(INET_NTOA(expr))

    例如:

    mysql> SELECT HEX(INET6_ATON(INET_NTOA(167773449)));
            -> '0A000509'

    如果从INET6_ATON()中调用,来自于mysql客户端时,二进制字符串将使用十六进制表示法显示,取决于--binary-as-hex的值。有关该选项的更多信息,请参见第6.5.1节,“mysql — The MySQL Command-Line Client”

  • INET6_NTOA(expr)

    给定一个以二进制字符串形式表示的 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 命令行客户端”

  • IS_IPV4(expr)

    如果参数是有效的IPv4地址字符串,返回1否则返回0。如果exprNULL,返回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()返回非NULLIS_IPV4()返回0。

    如前所述,IS_IPV4()INET_ATON()更严格地检查IPv4地址的有效性,因此在需要对无效值进行强制检查的应用程序中可能有用。或者,可以使用INET6_ATON()将IPv4地址转换为内部形式,并检查结果是否为NULL(表示无效地址)。INET6_ATON()在检查IPv4地址方面与IS_IPV4()等同。

  • IS_IPV4_COMPAT(expr)

    该函数将 IPv6 地址以数字形式作为二进制字符串传递,例如由INET6_ATON()返回的结果。它返回 1,如果参数是有效的 IPv4 兼容 IPv6 地址,否则返回 0(除非exprNULLNULL)。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,除非exprNULLNULL)。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
  • IS_IPV6(expr)

    如果参数是有效的 IPv6 地址字符串,则返回 1,否则返回 0,除非exprNULLNULL。该函数不考虑 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,如果参数不是有效的 UUID,则返回 0,如果参数为NULL,则返回NULL

    有效指的是该值可以被解析,即它具有正确的长度,并且只包含允许的字符(十六进制数字在任何大写或小写中,optional 的破折号和花括号)。这通常是最常见的格式:

    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。持续时间可能具有小数部分。如果参数为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(“A Universally Unique IDentifier (UUID) URN Namespace”)生成的通用唯一标识符(UUID)。(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 版本号。

    • 第四个数字保留了时间戳值在失去单调性的情况下的唯一性(例如, debido to daylight saving time)。

    • 第五个数字是 IEEE 802 节点号,提供空间唯一性。如果后者不可用(例如,因为主机设备没有以太网卡,或者不知道如何在主机操作系统上找到接口的硬件地址),则将使用随机数。在这种情况下,空间唯一性不能被保证。然而,碰撞的可能性应该非常低。

      接口的 MAC 地址仅在 FreeBSD、Linux 和 Windows 上被考虑。在其他操作系统上,MySQL 使用一个随机生成的 48 位数字。

    mysql> SELECT UUID();
            -> '6ccd780c-baba-1026-9564-5b8c656024db'

    要将字符串和二进制UUID值之间进行转换,可以使用UUID_TO_BIN()BIN_TO_UUID()函数。要检查字符串是否是有效的UUID值,可以使用IS_UUID()函数。

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

  • UUID_SHORT()

    返回一个short通用标识符作为64位无符号整数。由UUID_SHORT()返回的值不同于UUID()函数返回的128位字符串标识符,并且具有不同的唯一性属性。UUID_SHORT()的值保证是唯一的,如果满足以下条件:

    • 当前服务器的server_id值在0到255之间,并且在您的源服务器和副本服务器集群中唯一。

    • 在服务器主机重启mysqld之间,不要设置系统时间

    • mysqld重启之间,平均每秒调用UUID_SHORT()的次数少于16000000次

    构建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_uuidswap_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 格式,时间部分交换提供无益。关于版本 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时,也需要将时间部分交换(第二个参数为1):

    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 — The MySQL Command-Line Client”

  • VALUES(col_name)

    INSERT ... ON DUPLICATE KEY UPDATE 语句中,您可以在UPDATE子句中使用VALUES(col_name)函数,以引用INSERT语句的一部分的列值。换言之,VALUES(col_name)UPDATE子句中引用的是,如果没有重复键冲突发生时将被插入的col_name值。这一函数在多行插入中特别有用。函数仅在INSERT语句的ON DUPLICATE KEY UPDATE子句中有效,并且在其他情况下返回<code class="literal">NULL</code>。请参见第15.2.7.2节,“INSERT ... ON DUPLICATE KEY UPDATE Statement”

    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 Statement”