sql >> Base de Datos >  >> RDS >> MariaDB

MariaDB LENGTH() vs LENGTHB():¿Cuál es la diferencia?

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ándar OCTET_LENGTH() .
  • Oracle traduce la función LENGTH() a la función SQL estándar CHAR_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á traduciendo LENGTH() a OCTET_LENGTH() .
  • Sin embargo, cuando se ejecuta en modo Oracle (es decir, sql_mode=ORACLE ), traduce LENGTH() a CHAR_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() .