文档主页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  函数和运算符  /  其他函数

14.24 其他函数

表 14.34 其他函数

名称 说明
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 模式时,对于 MySQL 出于无法确定的原因拒绝您知道有效的查询的情况,对 GROUP BY 查询很有用。函数返回值和类型与其参数的返回值和类型相同,但不检查函数结果是否符合 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;也就是说,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。这等效于在启用 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 值的低位时间部分和高位时间部分未交换。字符串结果的顺序与二进制参数的顺序相同。

    • 双参数形式采用二进制 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 子句中的表达式完全匹配的表达式。该表达式不能是位置说明符。对于每个表达式,如果当前行中的表达式值为表示超级聚合值的 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 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 修饰符”

  • INET_ATON(expr)

    给定 IPv4 网络地址的点分十进制表示形式的字符串,返回一个整数,该整数表示网络字节顺序(大端序)的地址的数值。如果 INET_ATON() 无法理解其参数,或者 exprNULL,则返回 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() 用于此类地址。

    注意

    要存储由 INET_ATON() 生成的值,请使用 INT UNSIGNED 列,而不是有符号的 INT。如果使用有符号列,则无法正确存储第一个八位字节大于 127 的 IP 地址对应的值。请参见 第 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 地址所需的字节数超过了最大的整数类型,因此此函数返回的表示形式具有 VARBINARY 数据类型:VARBINARY(16) 用于 IPv6 地址,VARBINARY(4) 用于 IPv4 地址。如果参数不是有效的地址,或者为 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%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 映射地址。

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

  • 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。反之则不然:在某些情况下,当 IS_IPV4() 返回 0 时,INET_ATON() 返回非 NULL

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

  • IS_IPV4_COMPAT(expr)

    此函数接受以数字形式表示的 IPv6 地址作为二进制字符串,如 INET6_ATON() 返回的那样。如果参数是有效的 IPv4 兼容 IPv6 地址,则返回 1,否则返回 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 兼容地址的 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() 返回的那样。如果参数是有效的 IPv4 映射 IPv6 地址,则返回 1,否则返回 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 映射地址的 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,如果参数不是有效的 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(name,value)

    返回给定的值。当用于生成结果集列时,NAME_CONST() 会导致该列具有给定的名称。参数应该是常量。

    mysql> SELECT NAME_CONST('myname', 14);
    +--------+
    | myname |
    +--------+
    |     14 |
    +--------+

    此函数仅供内部使用。服务器在写入包含对本地程序变量引用的存储程序的语句时使用它,如第 27.8 节“存储程序二进制日志记录”中所述。您可能会在 mysqlbinlog 的输出中看到此函数。

    对于您的应用程序,您可以通过使用简单的别名来获得与刚才示例中完全相同的结果,如下所示

    mysql> SELECT 14 AS myname;
    +--------+
    | myname |
    +--------+
    |     14 |
    +--------+
    1 row in set (0.00 sec)

    有关列别名的更多信息,请参阅第 15.2.13 节“SELECT 语句”

  • SLEEP(duration)

    休眠(暂停)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 生成的通用唯一标识符 (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 时使用此函数,则会记录警告。

  • 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
    注意

    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 时,还应该将 BIN_TO_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 |
    +--------------------------------------+

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

  • VALUES(col_name)

    INSERT ... ON DUPLICATE KEY UPDATE 语句中,您可以在 UPDATE 子句中使用 VALUES(col_name) 函数来引用语句 INSERT 部分中的列值。换句话说,UPDATE 子句中的 VALUES(col_name) 指的是如果没有发生重复键冲突,将要插入的 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);
    重要

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