## 12.5 流量控制功能

[](<>)[](<>)

[](<>)

**表 12.7 流量控制运算符**

| 姓名 | 描述 |
| --- | --- |
| [`案子`](flow-control-functions.html#operator_case) | 案例操作员 |
| [`如果（）`](flow-control-functions.html#function_if) | if/else 构造 |
| [`IFNULL()`](flow-control-functions.html#function_ifnull) | 空 if/else 构造 |
| [`NULLIF()`](flow-control-functions.html#function_nullif) | 如果 expr1 = expr2 返回 NULL |

-   [](<>)

    [`案子 *`价值`* 什么时候 *`比较值`* 然后 *`结果`* [什么时候 *`比较值`* 然后 *`结果`* ...] [别的 *`结果`*] 结尾`](flow-control-functions.html#operator_case)

    [`案例 *`健康）状况`* 然后 *`结果`* [什么时候 *`健康）状况`* 然后 *`结果`* ...] [别的 *`结果`*] 结尾`](flow-control-functions.html#operator_case)

    [](<>)

    首先[`案子`](flow-control-functions.html#operator_case)语法返回*`结果`*为了第一`*`价值`*=*`比较值`*`比较是真的。第二种语法返回第一个条件为真的结果。如果没有比较或条件为真，则后面的结果`别的`被退回，或`空值`如果没有`别的`部分。

    笔记

    的语法[`案子`](flow-control-functions.html#operator_case) *操作员*这里描述的与 SQL 略有不同[`案子`](case.html) *陈述*描述于[第 13.6.5.1 节，“CASE 声明”](case.html)，用于在存储的程序中使用。这[`案子`](case.html)语句不能有`否则为空`子句，并以`结束案例`代替`结尾`.

    a的返回类型[`案子`](flow-control-functions.html#operator_case)表达式结果是所有结果值的聚合类型：

    -   如果所有类型都是数字，则聚合类型也是数字：

        -   如果至少一个参数是双精度，则结果是双精度。

        -   否则，如果至少有一个参数是[`十进制`](fixed-point-types.html)，结果是[`十进制`](fixed-point-types.html).

        -   否则，结果为整数类型（有一个例外）：

            -   如果所有整数类型都为有符号或无符号，则结果为相同符号且精度为所有指定整数类型中最高的（即[`小音`](integer-types.html),[`小灵通`](integer-types.html),[`中型`](integer-types.html),[`INT`](integer-types.html)， 要么[`大整数`](integer-types.html)）。

            -   如果有符号和无符号整数类型的组合，结果是有符号的，精度可能更高。例如，如果类型已签名[`INT`](integer-types.html)并且未签名[`INT`](integer-types.html), 结果有符号[`大整数`](integer-types.html).

            -   异常未签名[`大整数`](integer-types.html)结合任何有符号整数类型。结果是[`十进制`](fixed-point-types.html)具有足够的精度和比例 0。

    -   如果所有类型都是[`少量`](bit-type.html)，结果是[`少量`](bit-type.html).否则，[`少量`](bit-type.html)参数的处理方式类似于[`大整数`](integer-types.html).

    -   如果所有类型都是[`年`](year.html)，结果是[`年`](year.html).否则，`年`参数的处理方式类似于[`INT`](integer-types.html).

    -   如果所有类型都是字符串 ([`字符`](char.html)要么[`VARCHAR`](char.html))，结果是[`VARCHAR`](char.html)最大长度由操作数的最长字符长度决定。

    -   如果所有类型都是字符或二进制字符串，则结果为[`变量`](binary-varbinary.html).

    -   [`放`](set.html)和[`枚举`](enum.html)被视为类似[`VARCHAR`](char.html);结果是[`VARCHAR`](char.html).

    -   如果所有类型都是[`JSON`](json.html)，结果是[`JSON`](json.html).

    -   如果所有类型都是时间的，则结果是时间的：

        -   如果所有时间类型都是[`日期`](datetime.html), [`时间`](time.html)， 要么[`时间戳`](datetime.html)，结果是[`日期`](datetime.html), [`时间`](time.html)， 要么[`时间戳`](datetime.html)， 分别。

        -   否则，对于时间类型的混合，结果是[`约会时间`](datetime.html).

    -   如果所有类型都是`几何学`，结果是`几何学`.

    -   如果任何类型是[`斑点`](blob.html)，结果是[`斑点`](blob.html).

    -   对于所有其他类型组合，结果是[`VARCHAR`](char.html).

    -   文字`空值`类型聚合忽略操作数。

    ```
    mysql> SELECT CASE 1 WHEN 1 THEN 'one'
        ->     WHEN 2 THEN 'two' ELSE 'more' END;
            -> 'one'
    mysql> SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END;
            -> 'true'
    mysql> SELECT CASE BINARY 'B'
        ->     WHEN 'a' THEN 1 WHEN 'b' THEN 2 END;
            -> NULL
    ```

-   [](<>)

    [`如果（*`expr1`*,*`expr2`*,*`expr3`*)`](flow-control-functions.html#function_if)

    [](<>)

    如果*`expr1`*是`真的`(`*`expr1`* <> 0`和`*`expr1`* 不为空`),[`如果（）`](flow-control-functions.html#function_if)返回*`expr2`*.否则，它返回*`expr3`*.

    笔记

    还有一个[`如果`](if.html) *陈述*, 这不同于[`如果（）`](flow-control-functions.html#function_if) *功能*描述here。看[第 13.6.5.2 节，“IF 语句”](if.html).

    如果只有其中之一*`expr2`*要么*`expr3`*是明确的`空值`, 结果类型[`如果（）`](flow-control-functions.html#function_if)函数是非的类型`空值`表达。

    默认返回类型[`如果（）`](flow-control-functions.html#function_if)（当它存储到临时表中时可能很重要）计算如下：

    -   如果*`expr2`*要么*`expr3`*产生一个字符串，结果是一个字符串。

        如果*`expr2`*和*`expr3`*都是字符串，如果其中一个字符串区分大小写，则结果区分大小写。

    -   如果*`expr2`*要么*`expr3`*产生一个浮点值，结果是一个浮点值。

    -   如果*`expr2`*要么*`expr3`*产生一个整数，结果是一个整数。

    ```
    mysql> SELECT IF(1>2,2,3);
            -> 3
    mysql> SELECT IF(1<2,'yes','no');
            -> 'yes'
    mysql> SELECT IF(STRCMP('test','test1'),'no','yes');
            -> 'no'
    ```

-   [](<>)

    [`如果空（*`expr1`*,*`expr2`*)`](flow-control-functions.html#function_ifnull)

    [](<>)[](<>)

    如果*`expr1`*不是`空值`, [`IFNULL()`](flow-control-functions.html#function_ifnull)返回*`expr1`*;否则返回*`expr2`*.

    ```
    mysql> SELECT IFNULL(1,0);
            -> 1
    mysql> SELECT IFNULL(NULL,10);
            -> 10
    mysql> SELECT IFNULL(1/0,10);
            -> 10
    mysql> SELECT IFNULL(1/0,'yes');
            -> 'yes'
    ```

    默认返回类型[`如果空（*`expr1`*,*`expr2`*)`](flow-control-functions.html#function_ifnull)是两个表达式中更“一般”的一个，按顺序排列`细绳`,`真实的`， 要么`整数`.考虑基于表达式的表或 MySQL 必须在内部存储由[`IFNULL()`](flow-control-functions.html#function_ifnull)在临时表中：

    ```
    mysql> CREATE TABLE tmp SELECT IFNULL(1,'test') AS test;
    mysql> DESCRIBE tmp;
    +-------+--------------+------+-----+---------+-------+
    | Field | Type         | Null | Key | Default | Extra |
    +-------+--------------+------+-----+---------+-------+
    | test  | varbinary(4) | NO   |     |         |       |
    +-------+--------------+------+-----+---------+-------+
    ```

    在本例中，类型`测试`列是[`VARBINARY(4)`](binary-varbinary.html)（字符串类型）。

-   [](<>)

     [`NULLIF(*`expr1`*,*`expr2`*)`](flow-control-functions.html#function_nullif)

     [](<>)

    退货`空值`如果`*`expr1`* = *`expr2`*`为真，否则返回*`expr1`*.这与[`案例 *`expr1`* = *`expr2`* 否则为空 *`expr1`* 结尾`](flow-control-functions.html#operator_case).

    返回值与第一个参数具有相同的类型。

    ```
    mysql> SELECT NULLIF(1,1);
            -> NULL
    mysql> SELECT NULLIF(1,2);
            -> 1
    ```

    笔记

    MySQL 评估*`expr1`*如果参数不相等则两次。

    这些函数对系统变量值的处理在 MySQL 8.0.22 中发生了变化。对于这些函数中的每一个，如果第一个参数仅包含第二个参数使用的字符集和排序规则中存在的字符（并且它是常量），则使用后一个字符集和排序规则进行比较。在 MySQL 8.0.22 及更高版本中，系统变量值被处理为相同字符和排序规则的列值。使用这些函数和以前成功的系统变量的一些查询随后可能会因非法混合排序规则而被拒绝。在这种情况下，您应该将系统变量转换为正确的字符集和排序规则。
