Desde la versión 10.3.1, MariaDB ha incluido un LENGTH()
función y un LENGTHB()
función.
Ese segundo tiene una B
al final del nombre. Es algo así como Length A
y Length B
, excepto que Length A
no tiene la A
.
¿Confundido?
Lo estaba, cuando me encontré por primera vez con LENGTHB()
. Ya conocía LENGTH()
, entonces, ¿por qué la necesidad de una versión "B"?
Vamos a averiguarlo.
Compatibilidad con Oracle
De acuerdo con el problema 12783 de MariaDB, antes de LENGTHB()
fue introducido (y antes de LENGTH()
fue modificado) las cosas funcionaron así:
- MariaDB traduce la función
LENGTH()
a la función SQL estándarOCTET_LENGTH()
. - Oracle traduce la función
LENGTH()
a la función SQL estándarCHAR_LENGTH()
.
Entonces se tomó la decisión de cambiar LENGTH()
de MariaDB por lo que se comporta de manera diferente, dependiendo del modo SQL en el que se esté ejecutando. Específicamente:
- Cuando se ejecuta en modo predeterminado (es decir,
sql_mode=DEFAULT
), MariaDB continuará traduciendoLENGTH()
aOCTET_LENGTH()
. - Sin embargo, cuando se ejecuta en modo Oracle (es decir,
sql_mode=ORACLE
), traduceLENGTH()
aCHAR_LENGTH()
en su lugar.
Presentamos LENGTHB()
Lo que nos lleva al LENGTHB()
función.
El LENGTHB()
la función se agregó como parte del mismo trabajo.
LENGTHB()
es un sinónimo de OCTET_LENGTH()
independientemente del modo SQL. En otras palabras, LENGTHB()
se traduce a OCTET_LENGTH()
cuando sql_mode=DEFAULT
y cuando sql_mode=ORACLE
.
Esto nos permite usar LENGTHB()
en nuestro código sin preocuparnos de que se vea afectado por el sql_mode
del usuario configuración.
La diferencia
La diferencia entre estas dos funciones se describe en la siguiente tabla.
Función | Modo predeterminado | Modo oráculo |
---|---|---|
LENGTHB() | Devuelve el número de bytes. | Devuelve el número de caracteres. |
LENGTHB() | Devuelve el número de bytes. | Devuelve el número de bytes. |
Tenga en cuenta que esta diferencia solo está presente desde MariaDB 10.3.1. Antes de eso, LENGTHB()
no existe, y LENGTH()
simplemente se traduce a OCTET_LENGTH()
.
Ejemplo
Aquí hay un ejemplo que demuestra la diferencia entre LENGTH()
y LENGTHB()
.
Configuremos nuestra sesión para usar el modo predeterminado:
SET SESSION sql_mode=DEFAULT;
Mi sesión probablemente ya estaba en el modo predeterminado, pero no hay nada de malo en configurarlo explícitamente.
Ahora ejecutemos LENGTH()
y LENGTHB()
con el mismo argumento:
SELECT
LENGTH('café'),
LENGTHB('café');
Resultado:
+-----------------+------------------+ | LENGTH('café') | LENGTHB('café') | +-----------------+------------------+ | 5 | 5 | +-----------------+------------------+
Entonces, cuando están en modo predeterminado, ambos devuelven el mismo valor.
En este caso, ambos devolvieron 5
, porque hay 5 bytes en esa cadena (el é
el carácter usa 2 bytes, y todos los demás usan 1 byte cada uno).
Ahora cambiemos al modo Oracle:
SET SESSION sql_mode=ORACLE;
Ahora volvamos a ejecutar la declaración anterior:
SELECT
LENGTH('café'),
LENGTHB('café');
Resultado:
+-----------------+------------------+ | LENGTH('café') | LENGTHB('café') | +-----------------+------------------+ | 4 | 5 | +-----------------+------------------+
Esta vez hay una diferencia entre las dos funciones. Esta vez LENGTH()
devolvió 4
. Eso es 1 menos que antes.
Esto se debe a que LENGTH()
se comporta de manera diferente en el modo Oracle. Como se mencionó, cuando sql_mode=ORACLE
, el LENGTHB()
la función se traduce a CHAR_LENGTH()
, que devuelve el número de caracteres, no bytes.
En el ejemplo anterior, LENGTH()
devolvió el número de bytes porque, cuando sql_mode=DEFAULT
, se traduce como OCTET_LENGTH()
.