Od wersji 10.3.1 MariaDB zawierała zarówno LENGTH()
funkcja i LENGTHB()
funkcja.
Ten drugi ma B
na końcu nazwy. To trochę jak Length A
i Length B
, z wyjątkiem tego, że Length A
nie ma A
.
Zdezorientowany?
Tak było, kiedy po raz pierwszy spotkałem LENGTHB()
. Wiedziałem już o LENGTH()
, więc dlaczego potrzebna jest wersja „B”?
Dowiedzmy się.
Zgodność z Oracle
Zgodnie z wydaniem MariaDB 12783, przed LENGTHB()
został wprowadzony (i przed LENGTH()
został zmodyfikowany) wszystko działało tak:
- MariaDB tłumaczy funkcję
LENGTH()
do funkcji standardowej SQLOCTET_LENGTH()
. - Oracle tłumaczy funkcję
LENGTH()
do funkcji standardowej SQLCHAR_LENGTH()
.
Następnie podjęto decyzję o zmianie LENGTH()
MariaDB funkcji, dzięki czemu zachowuje się inaczej, w zależności od tego, w jakim trybie SQL jest uruchomiony. W szczególności:
- Gdy działa w trybie domyślnym (np.
sql_mode=DEFAULT
), MariaDB będzie nadal tłumaczyćLENGTH()
doOCTET_LENGTH()
. - Jednak podczas pracy w trybie Oracle (tj.
sql_mode=ORACLE
), tłumaczyLENGTH()
doCHAR_LENGTH()
zamiast tego.
Przedstawiamy LENGTHB()
Co prowadzi nas do LENGTHB()
funkcjonować.
LENGTHB()
funkcja została dodana w ramach tej samej pracy.
LENGTHB()
jest synonimem OCTET_LENGTH()
niezależnie od trybu SQL. Innymi słowy, LENGTHB()
tłumaczy na OCTET_LENGTH()
kiedy sql_mode=DEFAULT
a kiedy sql_mode=ORACLE
.
Dzięki temu możemy użyć LENGTHB()
w naszym kodzie bez martwienia się, że ma na to wpływ sql_mode
użytkownika ustawienia.
Różnica
Różnicę między tymi dwiema funkcjami przedstawiono w poniższej tabeli.
Funkcja | Tryb domyślny | Tryb Oracle |
---|---|---|
LENGTH() | Zwraca liczbę bajtów. | Zwraca liczbę znaków. |
LENGTHB() | Zwraca liczbę bajtów. | Zwraca liczbę bajtów. |
Zauważ, że ta różnica występuje tylko w MariaDB 10.3.1. Wcześniej LENGTHB()
nie istnieje, a LENGTH()
po prostu tłumaczy na OCTET_LENGTH()
.
Przykład
Oto przykład, który pokazuje różnicę między LENGTH()
i LENGTHB()
.
Ustawmy naszą sesję na tryb domyślny:
SET SESSION sql_mode=DEFAULT;
Moja sesja prawdopodobnie była już w trybie domyślnym, ale nie zaszkodzi jej jawne ustawienie.
Teraz uruchommy LENGTH()
i LENGTHB()
z tym samym argumentem:
SELECT
LENGTH('café'),
LENGTHB('café');
Wynik:
+-----------------+------------------+ | LENGTH('café') | LENGTHB('café') | +-----------------+------------------+ | 5 | 5 | +-----------------+------------------+
Tak więc w trybie domyślnym oba zwracają tę samą wartość.
W tym przypadku obaj zwrócili 5
, ponieważ w tym ciągu jest 5 bajtów (é
znak używa 2 bajtów, a wszystkie inne używają 1 bajtu każdy).
Przejdźmy teraz do trybu Oracle:
SET SESSION sql_mode=ORACLE;
Teraz powtórzmy powyższe stwierdzenie:
SELECT
LENGTH('café'),
LENGTHB('café');
Wynik:
+-----------------+------------------+ | LENGTH('café') | LENGTHB('café') | +-----------------+------------------+ | 4 | 5 | +-----------------+------------------+
Tym razem jest różnica między tymi dwiema funkcjami. Tym razem LENGTH()
zwrócono 4
. To o 1 mniej niż poprzednio.
Dzieje się tak, ponieważ LENGTH()
zachowuje się inaczej w trybie Oracle. Jak wspomniano, gdy sql_mode=ORACLE
, LENGTH()
funkcja tłumaczy na CHAR_LENGTH()
, który zwraca liczbę znaków – nie bajtów.
W poprzednim przykładzie LENGTH()
zwrócił liczbę bajtów, ponieważ gdy sql_mode=DEFAULT
, tłumaczy się to na OCTET_LENGTH()
.