Сообщить об ошибке.

MySQL: CONVERT() и CAST(), преобразование типов.

Содержание:


Преобразование типов в БД MySQL.

Синтаксис:

CAST(expr AS type)
CONVERT(expr, type)

MySQL функция CAST() принимает выражение expr любого типа и возвращает результирующее значение указанного типа type. Эта операция также может быть выражена функцией CONVERT(expr, type), что эквивалентно.

Если выражение равно NULL, то CAST() возвращает NULL. Функция CONVERT() ведет себя аналогичным образом.

Разрешены следующие значения типов type:

  • BINARY[(N)] [charset_info]: Создает строку с типом данных VARBINARY, за исключением того, что когда выражение expr пусто (нулевая длина), то тип результата - BINARY(0). Если задана необязательная длина N, то BINARY(N) будет использовать не более N байт аргумента. Значения короче N байтов дополняются байтами 0x00 до длины N. Если необязательная длина N не указана, то MySQL вычисляет максимальную длину из выражения expr. Если указанная или вычисленная длина превышает внутренний порог, то тип результата - BLOB. Если длина все еще слишком велика, то тип результата - LONGBLOB.

  • CHAR[(N)]: Создает строку с типом данных VARCHAR. за исключением того, что когда выражение expr пусто (нулевая длина), то тип результата - CHAR(0). Если задана необязательная длина N, то CHAR(N) будет использовать не более N символов аргумента. Для значений короче N символов - заполнение не выполняется. Если необязательная длина N не указана, то MySQL вычисляет максимальную длину из выражения expr. Если указанная или вычисленная длина превышает внутренний порог, то тип результата - TEXT. Если длина все еще слишком велика, то тип результата - LONGTEXT.

    Без предложения charset_info, тип CHAR создает строку с набором символов по умолчанию. Для явного указания набора символов разрешены следующие значения charset_info:

    • CHARACTER SET charset_name: создает строку с заданным набором символов.
    • ASCII: сокращение для CHARACTER SET latin1.
    • UNICODE: сокращение для CHARACTER SET ucs2.

    Во всех случаях строка имеет параметры сортировки по умолчанию для заданной кодировки.

  • DATE: Создает значение DATE.

  • DATETIME[(М)]: Создает значение DATETIME. Если задано необязательное значение M, то оно указывает точность долей секунды.

  • DECIMAL[(M[,D])]: Создает значение DECIMAL. Если заданы необязательные значения M и D, они определяют максимальное количество цифр (точность) и количество цифр после запятой (масштаб). Если D опущен, то предполагается 0. Если М опущен, предполагается 10.

  • DOUBLE: Создает значение DOUBLE. Добавлено в MySQL 8.0.17.

  • FLOAT[(p)]: Если точность p не указана, то выдает результат типа FLOAT. Если указан p и находится в пределах 0 <= p <= 24, результат имеет тип FLOAT. Если 25 <= p <= 53, то результат имеет тип DOUBLE. Еслиp p < 0 или p > 53, возвращается ошибка. Добавлено в MySQL 8.0.17.

  • NCHAR[(N)]: Аналогично CHAR, но создает строку с национальным набором символов. В отличие от CHAR, NCHAR не позволяет указывать информацию о наборе символов в конце.

  • REAL: Создает значение типа REAL. На самом деле это FLOAT, если включен режим SQL REAL_AS_FLOAT, в противном случае результат имеет тип DOUBLE.

  • SIGNED [INTEGER]: Создает значение BIGINT со знаком.

  • TIME[(М)]: Создает значение TIME. Если задано необязательное значение M, то оно указывает точность долей секунды.

  • UNSIGNED [INTEGER]: Создает беззнаковое значение BIGINT.

  • YEAR: Создает значение YEAR. Добавлено в MySQL 8.0.22. Следующие правила регулируют преобразование в YEAR:

    • Для четырехзначного числа в диапазоне 1901–2155 включительно или для строки, которую можно интерпретировать как четырехзначное число в этом диапазоне, возвращает соответствующее значение YEAR.

    • Для числа, состоящего из одной или двух цифр, или для строки, которая может быть интерпретирована как такое число, возвращает значение YEAR следующим образом:

    • Если число находится в диапазоне от 1 до 69 включительно, то добавляет 2000 и возвращает сумму.

    • Если число находится в диапазоне от 70 до 99 включительно, то добавляет 1900 и возвращает сумму.

    • Для строки, которая оценивается как 0, возвращает 2000.

    • Для числа 0 возвращает 0.

    • Для значения DATE, DATETIME или TIMESTAMP возвращает часть значения YEAR.

    • Для значения TIME возвращает текущий год.

    • Если аргумент имеет тип DECIMAL, DOUBLE, DECIMAL или REAL, то округляет значение до ближайшего целого числа, а затем попытается привести значение к YEAR, используя правила для целочисленных значений.

      mysql> SELECT CAST(1944.35 AS YEAR), CAST(1944.50 AS YEAR);
           -> 1944, 1945
      mysql> SELECT CAST(66.35 AS YEAR), CAST(66.50 AS YEAR);
           -> 2066, 2067
      
  • Для значения, которое не может быть успешно преобразовано в YEAR, верните NULL.

Преобразование кодировки строки/записи в БД MySQL.

Функция CONVERT() с предложением USING в MySQL преобразует данные между наборами символов (кодировками).

Синтаксис функции CONVERT(), которая преобразует данные между кодировками:

CONVERT(expr USING transcoding_name)

В MySQL имена транскодирования совпадают с соответствующими именами наборов символов (кодировок).

Примеры:

SELECT CONVERT('test' USING utf8mb4);
SELECT CONVERT(_latin1 'Müller' USING utf8mb4);
INSERT INTO utf8mb4_table (utf8mb4_column)
    SELECT CONVERT(latin1_column USING utf8mb4) FROM latin1_table;

Для преобразования строк между наборами символов (кодировками) также можно использовать синтаксис CONVERT(expr, type) (без USING) или CAST(expr AS type), что эквивалентно:

Синтаксис функции CAST() и CONVERT() без использования USING:

CAST(string AS CHAR[(N)] CHARACTER SET charset_name)
CONVERT(string, CHAR[(N)] CHARACTER SET charset_name)

Примеры:

SELECT CONVERT('Привет', CHAR CHARACTER SET utf8mb4);
SELECT CAST('Привет' AS CHAR CHARACTER SET utf8mb4);

Если указать CHARACTER SET charset_name, как показано выше, то набор символов и сопоставление результата будут charset_name и сопоставлением по умолчанию charset_name. Если опустить CHARACTER SET charset_name, то набор символов и сопоставление результата определяются системными переменными character_set_connection и collation_connection (устанавливаются в конфигурации сервера MySQL), которые определяют набор символов и сопоставление соединения по умолчанию.

Предложение COLLATE не разрешено в вызовах CONVERT() или CAST(), но можно применить его к результату функции. Например:

SELECT CONVERT('Привет' USING utf8mb4) COLLATE utf8mb4_bin;
SELECT CONVERT('Привет', CHAR CHARACTER SET utf8mb4) COLLATE utf8mb4_bin;
SELECT CAST('Привет' AS CHAR CHARACTER SET utf8mb4) COLLATE utf8mb4_bin;

Для строковых литералов другим способом указать набор символов является использование интродьюсера набора символов (кодировки). В примере ниже, _latin1, _cp1251 и _utf8 являются экземплярами интродьюсеров. В отличие от функций преобразования, таких как CAST() или CONVERT(), которые преобразуют строку из одного набора символов в другой, интродьюсер определяет строковый литерал как имеющий определенный набор символов без участия преобразования.

SELECT CONVERT(_utf8 'Привет' USING cp1251);
        -> 'Привет'

Список доступных кодировок и сопоставлений, поддерживаемых MySQL-сервером можно получить командами:

-- список доступных кодировок
SHOW CHARACTER SET;
-- список доступных кодировок 
-- для сопоставления (сортировки)
SHOW COLLATION;

Преобразование кодировки при сравнения строк.

Обычно нельзя сравнивать значение BLOB или другую двоичную строку без учета регистра, потому что двоичные строки не связаны с понятием регистра букв. Чтобы выполнить сравнение без учета регистра, сначала нужно использовать функцию CONVERT() или CAST() для преобразования значения в недвоичную строку. Сравнения результирующей строки используют ее сопоставление. Например, если при сопоставлении результатов преобразования не учитывается регистр, то операция LIKE не учитывает регистр. Это верно для следующей операции, т.к. параметры сортировки utf8mb4 по умолчанию (utf8mb4_0900_ai_ci) не учитывают регистр:

SELECT 'A' LIKE CONVERT(blob_col USING utf8mb4)
  FROM tbl_name;

Чтобы указать конкретное сопоставление для преобразованной строки, используйте предложение COLLATE после вызова CONVERT():

SELECT 'A' LIKE CONVERT(blob_col USING utf8mb4) COLLATE utf8mb4_unicode_ci
  FROM tbl_name;

Чтобы использовать другой набор (кодировку) символов, замените его имя на utf8mb4 в предыдущих операторах (и аналогично, чтобы использовать другое сопоставление).

Функции CONVERT() и CAST() можно использовать в более широком смысле для сравнения строк, представленных в разных наборах символов. Например:

mysql> SET @s1 = _latin1 'abc', @s2 = _latin2 'abc';
mysql> SELECT @s1 = @s2;
-- ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT)
-- and (latin2_general_ci,IMPLICIT) for operation '='

Преобразование одной из строк в набор символов, совместимый с другой, позволяет выполнить сравнение без ошибок:

mysql> SELECT @s1 = CONVERT(@s2 USING latin1);
        -> 1

Преобразование набора символов также полезно перед преобразованием двоичных строк в верхний или нижний регистр. Функции LOWER() и UPPER() неэффективны при непосредственном применении к двоичным строкам, поскольку не применяется концепция регистра букв. Чтобы выполнить буквенное преобразование двоичной строки, сначала необходимо преобразовать ее в обычную строку, используя набор символов, соответствующий данным, хранящимся в строке:

mysql> SET @str = BINARY 'ПРИВЕТ';
mysql> SELECT LOWER(@str), LOWER(CONVERT(@str USING utf8mb4));
        -> 'ПРИВЕТ', 'привет'