Още от версия 10.3.1, MariaDB включва както LENGTH() функция и LENGTHB() функция.
Този втори има B в края на името. Така че е нещо като Length A и Length B , с изключение на това Length A няма A .
Объркан?
Бях, когато за първи път срещнах LENGTHB() . Вече знаех за LENGTH() , така че защо е необходима версия „B“?
Нека разберем.
Съвместимост с Oracle
Според MariaDB проблем 12783, преди LENGTHB() беше въведен (и преди LENGTH() беше променен) нещата работеха така:
- MariaDB превежда функцията
LENGTH()към стандартната функция на SQLOCTET_LENGTH(). - Oracle превежда функцията
LENGTH()към стандартната функция на SQLCHAR_LENGTH().
След това беше взето решение да се промени LENGTH() на MariaDB функция, така че да се държи различно, в зависимост от режима на SQL, в който работи. По-конкретно:
- Когато работи в режим по подразбиране (т.е.
sql_mode=DEFAULT), MariaDB ще продължи да превеждаLENGTH()доOCTET_LENGTH(). - Въпреки това, когато работите в режим на Oracle (т.е.
sql_mode=ORACLE), той превеждаLENGTH()доCHAR_LENGTH()вместо това.
Представяме LENGTHB()
Което ни отвежда до LENGTHB() функция.
LENGTHB() функцията беше добавена като част от същата работа.
LENGTHB() е синоним на OCTET_LENGTH() независимо от режима на SQL. С други думи, LENGTHB() се превежда в OCTET_LENGTH() когато sql_mode=DEFAULT и когато sql_mode=ORACLE .
Това ни позволява да използваме LENGTHB() в нашия код, без да се притеснявате, че ще бъде засегнат от sql_mode на потребителя настройки.
Разликата
Разликата между тези две функции е очертана в следващата таблица.
| Функция | Режим по подразбиране | Режим Oracle |
|---|---|---|
LENGTH() | Връща броя на байтовете. | Връща броя на знаците. |
LENGTHB() | Връща броя на байтовете. | Връща броя на байтовете. |
Имайте предвид, че тази разлика е налице само от MariaDB 10.3.1. Преди това LENGTHB() не съществува и LENGTH() просто се превежда в OCTET_LENGTH() .
Пример
Ето пример, който демонстрира разликата между LENGTH() и LENGTHB() .
Нека настроим нашата сесия да използва режима по подразбиране:
SET SESSION sql_mode=DEFAULT; Сесията ми вероятно вече беше в режим по подразбиране, но няма нищо лошо да я задам изрично.
Сега нека изпълним LENGTH() и LENGTHB() със същия аргумент:
SELECT
LENGTH('café'),
LENGTHB('café'); Резултат:
+-----------------+------------------+
| LENGTH('café') | LENGTHB('café') |
+-----------------+------------------+
| 5 | 5 |
+-----------------+------------------+ Така че, когато са в режим по подразбиране, и двете връщат една и съща стойност.
В този случай и двамата върнаха 5 , защото в този низ има 5 байта (é символът използва 2 байта, а всички останали използват по 1 байт).
Сега нека преминем към режим на Oracle:
SET SESSION sql_mode=ORACLE; Сега нека повторим горното изявление:
SELECT
LENGTH('café'),
LENGTHB('café'); Резултат:
+-----------------+------------------+
| LENGTH('café') | LENGTHB('café') |
+-----------------+------------------+
| 4 | 5 |
+-----------------+------------------+
Този път има разлика между двете функции. Този път LENGTH() върна 4 . Това е с 1 по-малко от преди.
Това е така, защото LENGTH() се държи различно в режим на Oracle. Както споменахме, когато sql_mode=ORACLE , LENGTH() функцията се превежда в CHAR_LENGTH() , който връща броя на знаците, а не на байтовете.
В предишния пример LENGTH() върна броя на байтовете, защото, когато sql_mode=DEFAULT , превежда се на OCTET_LENGTH() .