Я хочу вставить запись в MySQL с символом Unicode, отличным от ASCII, но я нахожусь на терминале, который не позволяет мне легко печатать символы, отличные от ASCII. Как избежать символа Unicode в синтаксисе SQL SQL?
MySQL unicode литералы
Ответ 1
См.: http://bugs.mysql.com/bug.php?id=10199 (Ошибка # 10199: "Разрешить escape-последовательность Unicode для строковых литералов".) Этот запрос был "Открыт" с 2005 года. Подробнее в Worklog Task # 3529: Unicode Escape-последовательности.
Из https://web.archive.org/web/20091117221116/http://eng.kaching.com/2009/10/mysql-unicode-escape-sequence.html вы можете увидеть следующий пример, который на самом деле кажется, работает, но требует, чтобы вы знали фактическую побайтовую кодировку UTF8:
Вы также можете использовать представление UTF-8 переменной длины (удобно, например, при копировании из URL-значения в кодировке utf-8, такого как% E2% 80% 98).
mysql> select _utf8 x'E28098'; +---+ | ‘ | +---+
Ответ 2
Эта хранимая функция предоставляет функциональность MySQL (по-видимому) отсутствует, с возможностью превратить литеральную точку кода в символ без необходимости знать кодировку UTF-8.
Если VARCHAR(1)
кажется странным, так как символы utf8 в MySQL могут иметь длину до 3 байтов, помните, что размер VARCHAR
- это символы, а не байты. Функция возвращает один символ с кодировкой UTF-8 из входного значения.
Для шестнадцатеричных литералов добавьте 0x
.
DELIMITER $$
DROP FUNCTION IF EXISTS `utf8_char` $$
CREATE FUNCTION `utf8_char`(v smallint unsigned) RETURNS VARCHAR(1) CHARSET utf8
NO SQL
DETERMINISTIC
BEGIN
-- http://stackoverflow.com/questions/3632410/mysql-unicode-literals/30675371#30675371
RETURN CHAR(CASE
WHEN v <= 0x7F THEN v
WHEN v <= 0x7FF THEN 0xC080 | ((v >> 6) << 8) | (v & 0x3F)
WHEN v <= 0xFFFF THEN 0xE08080 | (((v >> 12) & 0x0F ) << 16) | (((v >> 6) & 0x3F ) << 8) | (v & 0x3F)
ELSE NULL END);
END $$
DELIMITER ;
Пример вывода:
mysql> select utf8_char(8592) AS 'leftwards_arrow';
+-----------------+
| leftwards_arrow |
+-----------------+
| ← |
+-----------------+
1 row in set (0.00 sec)
mysql> select utf8_char(0x2192) AS 'rightwards_arrow_hex';
+----------------------+
| rightwards_arrow_hex |
+----------------------+
| → |
+----------------------+
1 row in set (0.00 sec)
Ответ 3
Если цель состоит в том, чтобы указать кодовую точку вместо кодированной последовательности байтов (т. 0x0F02
вместо UTF-8 0xE0BC82
для "༂"), то вам необходимо использовать кодировку, в которой значение кодовой точки просто оказывается закодированным последовательность байтов. Например, "0xE28098" является UTF-8, кодированной последовательностью байт для "'" характера (как показано на dkamins ответа), который является кодовой точкой U + 2018. Однако 0x2018
является одновременно значением кодовой точки для '
и закодированной байтовой последовательностью для ucs2
/utf16
(они фактически являются одинаковыми кодировками для символов BMP, но я предпочитаю использовать "utf16", поскольку это согласуется с "utf8" и "utf32" ", соответствует теме" UTF "). Следовательно:
_utf16 0x2018
возвращает тот же самый '
характер, как:
_utf8 0xE0BC82
Но utf16
работает только для символов BMP (кодовые точки U + 0000 - U + FFFF) с точки зрения указания значения кодовой точки. Если вам нужен дополнительный символ (указав кодовую точку вместо конкретной последовательности кодирования байтов), вам нужно будет использовать кодировку utf32
. _utf32 0x2018
возвращает не только '
, но и:
_utf32 0x1F47E
возвращает: 👾
Для использования кодировок UTF-8 или UTF-16 для этого же дополнительного символа потребуется следующее:
_utf8mb4 0xF09F91BE
_utf16 0xD83DDC7E
ОДНАКО, если у вас возникли проблемы с добавлением этого в строку, которая уже является utf8, вам нужно будет преобразовать это в utf8
(или в utf8mb4
при создании дополнительных символов, так как кодировка/кодировка utf8
может обрабатывать только символы BMP):
CONVERT(_utf32 0x1F47E USING utf8mb4)
Или, используя пример символа от Михаэля - ответ sqlbot:
CONVERT(_utf32 0x2192 USING utf8)
возвращает →
. Следовательно, пользовательская функция не требуется для того, чтобы создавать кодированный символ UTF-8 из его кодовой точки (по крайней мере, не в MySQL 8.0). Вот тестовый запрос
SELECT _utf32 0x1F47E AS "Supplementary Character in utf32",
CONVERT(_utf32 0x1F47E USING utf8mb4) AS "Supplementary Character in utf8mb4",
CHARSET(CONVERT(_utf32 0x1F47E USING utf8mb4)) AS "Proof",
"---" AS "---",
_utf32 0x2192 AS "BMP character in utf32",
CONVERT(_utf32 0x2192 USING utf8) AS "BMP character in utf8",
CHARSET(CONVERT(_utf32 0x2192 USING utf8)) AS "Proof";
И вы можете видеть, что он работает на db <> fiddle (может не работать в MySQL до 8.0).
Для получения более подробной информации об этих опциях, а также escape-последовательностях Unicode для других языков и платформ, пожалуйста, смотрите мой пост:
Unicode Escape-последовательности на разных языках и платформах (включая дополнительные символы)