Desde a versão 10.3.1, o MariaDB incluiu um
LENGTH()
função e um LENGTHB()
função. Esse segundo tem um
B
no final do nome. Então é como Length A
e Length B
, exceto que Length A
não tem o A
. Confuso?
Eu estava, quando encontrei
LENGTHB()
pela primeira vez . Eu já sabia sobre LENGTH()
, então por que a necessidade de uma versão “B”? Vamos descobrir.
Compatibilidade com Oracle
De acordo com o problema 12783 do MariaDB, antes de
LENGTHB()
foi introduzido (e antes de LENGTH()
foi modificado) as coisas funcionaram assim:- MariaDB traduz a função
LENGTH()
para a função padrão SQLOCTET_LENGTH()
. - O Oracle traduz a função
LENGTH()
para a função padrão SQLCHAR_LENGTH()
.
Foi então tomada a decisão de alterar o
LENGTH()
do MariaDB função para que se comporte de maneira diferente, dependendo do modo SQL em que está sendo executado. Especificamente:- Ao executar no modo padrão (ou seja,
sql_mode=DEFAULT
), MariaDB continuará traduzindoLENGTH()
paraOCTET_LENGTH()
. - No entanto, ao executar no modo Oracle (ou seja,
sql_mode=ORACLE
), ele traduzLENGTH()
paraCHAR_LENGTH()
em vez disso.
Apresentando LENGTHB()
O que nos leva ao
LENGTHB()
função. O
LENGTHB()
função foi adicionada como parte do mesmo trabalho. LENGTHB()
é sinônimo de OCTET_LENGTH()
independentemente do modo SQL. Em outras palavras, LENGTHB()
traduz para OCTET_LENGTH()
quando sql_mode=DEFAULT
e quando sql_mode=ORACLE
. Isso nos permite usar
LENGTHB()
em nosso código sem se preocupar em ser afetado pelo sql_mode
do usuário definições. A diferença
A diferença entre essas duas funções é descrita na tabela a seguir.
Função | Modo padrão | Modo Oráculo |
---|---|---|
LENGTH() | Retorna o número de bytes. | Retorna o número de caracteres. |
LENGTHB() | Retorna o número de bytes. | Retorna o número de bytes. |
Observe que essa diferença está presente apenas no MariaDB 10.3.1. Antes disso,
LENGTHB()
não existe e LENGTH()
simplesmente traduz para OCTET_LENGTH()
. Exemplo
Aqui está um exemplo que demonstra a diferença entre
LENGTH()
e LENGTHB()
. Vamos configurar nossa sessão para usar o modo padrão:
SET SESSION sql_mode=DEFAULT;
Minha sessão provavelmente já estava no modo padrão, mas não há mal nenhum em defini-la explicitamente.
Agora vamos executar
LENGTH()
e LENGTHB()
com o mesmo argumento:SELECT
LENGTH('café'),
LENGTHB('café');
Resultado:
+-----------------+------------------+ | LENGTH('café') | LENGTHB('café') | +-----------------+------------------+ | 5 | 5 | +-----------------+------------------+
Portanto, quando no modo padrão, ambos retornam o mesmo valor.
Nesse caso, ambos retornaram
5
, porque há 5 bytes nessa string (o é
caractere usa 2 bytes e todos os outros usam 1 byte cada). Agora vamos mudar para o modo Oracle:
SET SESSION sql_mode=ORACLE;
Agora vamos executar novamente a declaração acima:
SELECT
LENGTH('café'),
LENGTHB('café');
Resultado:
+-----------------+------------------+ | LENGTH('café') | LENGTHB('café') | +-----------------+------------------+ | 4 | 5 | +-----------------+------------------+
Desta vez, há uma diferença entre as duas funções. Desta vez
LENGTH()
retornou 4
. Isso é 1 a menos do que anteriormente. Isso ocorre porque
LENGTH()
se comporta de forma diferente no modo Oracle. Como mencionado, quando sql_mode=ORACLE
, o LENGTH()
função traduz para CHAR_LENGTH()
, que retorna o número de caracteres – não bytes. No exemplo anterior,
LENGTH()
retornou o número de bytes porque, quando sql_mode=DEFAULT
, ele se traduz em OCTET_LENGTH()
.