文档主页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


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

14.23 其他函数

表 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 期间要使用的值

  • 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 列中命名,也不在函数上依赖于它们。 因此,每个 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 值的 time-low 和 time-high 部分未交换。字符串结果与二进制参数的顺序相同。

    • 双参数形式采用二进制 UUID 值和一个交换标志值。

      • 如果 swap_flag 为 0,则双参数形式等效于单参数形式。字符串结果与二进制参数的顺序相同。

      • 如果 swap_flag 为 1,则假定 UUID 值的 time-low 和 time-high 部分已交换。在结果值中,这些部分将交换回其原始位置。

    有关使用示例和时间部分交换的信息,请参阅 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()a 用于此类地址。

    注意

    要存储由 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 数据类型: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%1fe80::3%eth0 中所示。

    • 不允许使用尾随网络掩码,如 2001:45f:3:ba::/64198.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 命令行客户端”

  • 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.7 节,“存储程序二进制日志记录” 中所述。您可能会在 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 时,您还应将第二个参数 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 命令行客户端”

  • VALUES(列名)

    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 语句”