Spec-Zone.ru › MySQL 5.7

12.20 Вспомогательные функции

Таблица 12.26 Вспомогательные функции

Таблица 12.26 Вспомогательные функции
Имя Описание
ANY_VALUE() Подавление отклонения значения ONLY_FULL_GROUP_BY
DEFAULT() Возвращает значение по умолчанию для столбца таблицы
INET_ATON() Возвращает числовое значение IP-адреса
INET_NTOA() Возвращает IP-адрес из числового значения
INET6_ATON() Возвращает числовое значение адреса IPv6
INET6_NTOA() Возвращает адрес IPv6 из числового значения
IS_IPV4() Является ли аргумент адресом IPv4
IS_IPV4_COMPAT() Является ли аргумент IPv4-совместимым адресом
IS_IPV4_MAPPED() Является ли аргумент IPv4-отображённым адресом
IS_IPV6() Является ли аргумент адресом IPv6
NAME_CONST() Задает столбцу указанное имя
SLEEP() Отложить выполнение на заданное количество секунд
UUID() Возвращает универсальный уникальный идентификатор (UUID)
UUID_SHORT() Возвращает целочисленное значение универсального идентификатора
VALUES() Определяет значения, которые будут использоваться при INSERT

  • ANY_VALUE(arg)

    Эта функция полезна для GROUP BY запросов, когда включен режим SQL ONLY_FULL_GROUP_BY, в случаях, когда MySQL отклоняет запрос, который, по вашему мнению, является корректным по причинам, которые MySQL не может определить. Значение и тип возвращаемого результата функции совпадают со значением и типом её аргумента, но результат функции не проверяется на соответствие режиму SQL ONLY_FULL_GROUP_BY.

    Например, если 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 определить, что address функционально зависит от name; то есть, address однозначно определяется name. (Этот метод неприменим, если NULL должен быть допустимым значением name.)

    • Используйте ANY_VALUE() для ссылки на address:

      SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;
      

      В этом случае MySQL игнорирует недетерминированность значений address внутри каждой name группы и принимает запрос. Это может быть полезно, если вам просто неважно, какое значение столбца без агрегирования выбирается для каждой группы. 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;
    

    Возможно, из-за определённого свойства набора данных вы знаете, что выбранный столбец без агрегирования фактически функционально зависит от столбца группирования. Например, приложение может обеспечить уникальность одного столбца относительно другого. В этом случае использование ANY_VALUE() для фактически функционально зависимого столбца может иметь смысл.

    Для дополнительной информации см. Раздел 12.19.3, «Обработка GROUP BY в MySQL».

  • DEFAULT(col_name)

    Возвращает значение по умолчанию для столбца таблицы. Возникает ошибка, если у столбца нет значения по умолчанию.

    mysql> UPDATE t SET i = DEFAULT(i)+1 WHERE id < 100;
    
  • FORMAT(X,D)

    Форматирует число X в формат, подобный '#,###,###.##', округлённый до D десятичных знаков, и возвращает результат как строку. Подробнее см. Раздел 12.8, «Функции и операторы для строк».

  • INET_ATON(expr)

    Принимая строковое представление IP-адреса IPv4 в формате точка-десятичная, возвращает целое число, которое представляет собой числовое значение адреса в сетевом порядке байтов (big endian). INET_ATON() возвращает NULL, если не может распознать свой аргумент.

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

    В данном примере возвращаемое значение рассчитывается как 10×2563 + 0×2562 + 5×256 + 9.

    INET_ATON() может или не может возвращать результат, отличный от NULL для сокращённых IP-адресов (например, '127.1' как представление '127.0.0.1'). Из-за этого INET_ATON() не следует использовать для таких адресов.

    Примечание

    Для хранения значений, сгенерированных функцией INET_ATON(), используйте столбец типа INT UNSIGNED, а не INT, который со знаком. Если вы используете столбец со знаком, значения, соответствующие IP-адресам, первый октет которых больше 127, не могут быть сохранены правильно. См. Раздел 11.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: VARBINARY(16) для IPv6 адресов и VARBINARY(4) для IPv4 адресов. Если аргумент не является корректным адресом, 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() соблюдает несколько ограничений для допустимых аргументов. Они приведены в следующем списке вместе с примерами.

    • Запрещена приставка с идентификатором зоны, как в fe80::3%1 или fe80::3%eth0.

    • Запрещена приставка с маской сети, как в 2001:45f:3:ba::/64 или 198.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 также применяются к IPv6 адресам, содержащим части IPv4 адресов, таким как 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. Дополнительную информацию об этом параметре см. в Разделе 4.5.1, «mysql — Клиент командной строки MySQL».

  • INET6_NTOA(expr)

    Принимая в качестве аргумента двоичную строку, представляющую IPv6 или IPv4 сетевой адрес в числовом формате, возвращает строковое представление адреса в строковом формате набора символов соединения. Если аргумент не является корректным адресом, 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 utf8 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'
    

    Если INET6_NTOA() вызывается из клиента mysql, двоичные строки отображаются в шестнадцатеричном формате, в зависимости от значения параметра --binary-as-hex. Дополнительную информацию об этом параметре см. в Разделе 4.5.1, «mysql — Клиент командной строки MySQL».

  • IS_IPV4(expr)

    Возвращает 1, если аргумент является корректным IPv4 адресом, указанным в строке, и 0 в противном случае.

    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() возвращает значение отличное от NULL, когда IS_IPV4() возвращает 0.

    Как подразумевается из предыдущих замечаний, IS_IPV4() более строго, чем INET_ATON(), в отношении того, что считается корректным IPv4 адресом, поэтому может быть полезен для приложений, которым необходимо выполнять строгие проверки на недопустимые значения. В качестве альтернативы, используйте INET6_ATON() для преобразования IPv4 адресов во внутренний формат и проверки результата на NULL (что указывает на некорректный адрес). INET6_ATON() аналогично IS_IPV4() в отношении проверки IPv4 адресов.

  • MASTER_POS_WAIT(log_name,log_pos[,timeout][,channel])

    Эта функция полезна для управления синхронизацией источника и реплики. Она блокируется, пока реплика не прочитает и не применит все обновления до указанной позиции в журнале источника. Значение возврата — это количество событий журнала, которые реплике пришлось ждать, чтобы перейти к указанной позиции. Функция возвращает NULL, если поток SQL реплики не запущен, информация о источнике реплики не инициализирована, аргументы некорректны или произошла ошибка. Она возвращает -1, если истекло время ожидания. Если поток SQL реплики останавливается во время ожидания MASTER_POS_WAIT(), функция возвращает NULL. Если реплика прошла указанную позицию, функция возвращает результат немедленно.

    В многопотоковой реплике функция ждет до истечения лимита, установленного системной переменной slave_checkpoint_group или slave_checkpoint_period, когда операция контрольной точки вызывается для обновления статуса реплики. В зависимости от настроек системных переменных, функция может вернуть значение некоторое время спустя после достижения указанной позиции.

    Если указано значение timeout, MASTER_POS_WAIT() перестаёт ожидать, когда прошло timeout секунд. timeout должно быть больше или равно 0. (Начиная с MySQL 5.7.18, когда сервер работает в строгом режиме SQL, отрицательное значение timeout сразу отклоняется; в противном случае функция возвращает NULL и выводит предупреждение.)

    Необязательное значение channel позволяет указать репликационный канал, к которому применяется функция. Дополнительную информацию см. в Разделе 16.2.2, «Репликационные каналы».

    Эта функция небезопасна для репликации на основе заявлений. Предупреждение записывается в журнал, если вы используете эту функцию, когда binlog_format установлено в значение STATEMENT.

  • NAME_CONST(name,value)

    Возвращает заданное значение. При использовании для создания столбца результата NAME_CONST() приводит к тому, что столбец получает заданное имя. Аргументы должны быть константами.

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

    Эта функция предназначена только для внутреннего использования. Сервер использует её при записи операторов из хранимых программ, содержащих ссылки на локальные переменные программы, как описано в Разделе 23.7, «Логирование двоичных данных хранимых программ». Вы можете увидеть эту функцию в выводе из mysqlbinlog.

    Для ваших приложений вы можете получить точно такой же результат, как в приведённом только что примере, используя простое алиасирование, например так:

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

    Дополнительную информацию об алиасах столбцов см. в Разделе 13.2.9, «Оператор 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()

    Возвращает универсальный уникальный идентификатор (UUID), сгенерированный в соответствии с RFC 4122, “Пространство имён URI универсального уникального идентификатора (UUID)” (http://www.ietf.org/rfc/rfc4122.txt).

    UUID разработан как число, которое является глобально уникальным в пространстве и во времени. Два вызова функции UUID() ожидаются для генерации двух различных значений, даже если эти вызовы выполняются на двух отдельных устройствах, не соединённых друг с другом.

    Предупреждение

    Хотя значения UUID() предназначены для уникальности, они не обязательно являются непредсказуемыми или не угадываемыми. Если требуется непредсказуемость, значения UUID должны быть сгенерированы каким-либо другим способом.

    UUID() возвращает значение, соответствующее версии 1 UUID, как описано в RFC 4122. Значение представляет собой 128-битное число, представленное как utf8 строка из пяти шестнадцатеричных чисел в формате aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:

    • Первые три числа генерируются из низких, средних и высоких частей временной метки. Высокая часть также включает номер версии UUID.

    • Четвёртое число сохраняет временную уникальность в случае, если значение временной метки теряет монотонность (например, из-за перехода на летнее время).

    • Пятое число — это номер узла IEEE 802, обеспечивающий пространственную уникальность. Случайное число подставляется, если последний недоступен (например, если устройство-хост не имеет сетевой карты Ethernet или неизвестно, как найти аппаратный адрес интерфейса в операционной системе хоста). В этом случае пространственная уникальность не может быть гарантирована. Тем не менее, столкновение должно иметь очень низкую вероятность.

      MAC-адрес интерфейса учитывается только на FreeBSD, Linux и Windows. В других операционных системах MySQL использует случайное 48-битное число.

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

    Эта функция небезопасна для репликации на основе заявлений. Предупреждение записывается в журнал, если вы используете эту функцию, когда binlog_format установлено в значение STATEMENT.

  • UUID_SHORT()

    Возвращает «короткий» универсальный идентификатор в виде 64-битного беззнакового целого числа. Значения, возвращаемые функцией UUID_SHORT(), отличаются от строковых 128-битных идентификаторов, возвращаемых функцией UUID(), и имеют другие свойства уникальности. Значение UUID_SHORT() гарантируется уникальным, если выполняются следующие условия:

    • Значение server_id текущего сервера находится в диапазоне от 0 до 255 и уникально среди вашего набора серверов источника и реплики

    • Вы не устанавливаете время системы для своего сервера между перезапусками mysqld

    • Вы вызываете функцию UUID_SHORT() в среднем менее 16 миллионов раз в секунду между перезапусками mysqld

    Значение возврата функции UUID_SHORT() формируется следующим образом:

      (server_id & 255) << 56
    + (server_startup_time_in_seconds << 24)
    + incremented_variable++;
    
    mysql> SELECT UUID_SHORT();
            -> 92395783831158784
    
    Примечание

    UUID_SHORT() не работает с репликацией на основе заявлений.

  • VALUES(col_name)

    В операторе INSERT ... ON DUPLICATE KEY UPDATE вы можете использовать функцию VALUES(col_name) в предложении UPDATE, чтобы сослаться на значения столбцов из части INSERT оператора. Другими словами, VALUES(col_name) в предложении UPDATE ссылается на значение col_name, которое было бы вставлено, если бы не произошло конфликта по уникальному ключу. Эта функция особенно полезна при вставке нескольких строк. Функция VALUES() имеет смысл только в предложении ON DUPLICATE KEY UPDATE операторов INSERT и возвращает NULL в противном случае. См. Раздел 13.2.5.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);
    

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/miscellaneous-functions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API