文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式 Letter) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (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 拒絕您知道有效的查詢,因為 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;也就是說,address 是由 name 唯一決定的。(如果必須允許 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 並傳回結果。二進位值應該是 UUID,以 VARBINARY(16) 值表示。傳回值是一個由破折號分隔的五個十六進制數字組成的字串。(有關此格式的詳細資訊,請參閱 UUID() 函數說明。)如果 UUID 引數為 NULL,則傳回值為 NULL。如果任何引數無效,則會發生錯誤。

    BIN_TO_UUID() 接受一個或兩個引數。

    • 單引數形式接受二進位 UUID 值。假定 UUID 值沒有交換其 time-low 和 time-high 部分。字串結果與二進位引數的順序相同。

    • 雙引數形式接受二進位 UUID 值和 swap-flag 值。

      • 如果 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 網路位址的點分四組表示法(以字串形式)轉換為表示位址數值(以網路位元組順序 (big endian))的整數。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 網路位址(以字串形式)轉換為表示位址數值(以網路位元組順序 (big endian))的二進位字串。由於數值格式的 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 位址的值,僅支援無類別位址。會拒絕類別位址,例如 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 網路位址(以二進位字串表示),此函數會以連線字元集中的字串形式,傳回位址的字串表示。如果引數不是有效的位址,或為 NULLINET6_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 值。

    如前述說明所示,關於何謂有效的 IPv4 位址,IS_IPV4()INET_ATON() 更為嚴格,因此它可能對需要針對無效值執行嚴格檢查的應用程式很有用。或者,可以使用 INET6_ATON() 將 IPv4 位址轉換為內部格式,並檢查是否傳回 NULL 結果(表示無效的位址)。關於 IPv4 位址的檢查,INET6_ATON()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 模式下產生錯誤。

    當休眠正常傳回時(沒有中斷),它會傳回 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 通用唯一 IDentifier (UUID) URN 命名空間 (http://www.ietf.org/rfc/rfc4122.txt) 產生的通用唯一識別碼 (UUID)。

    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 時,也應將第二個參數 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 — The MySQL Command-Line Client"

  • 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 Statement"

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