Una función para obtener la cantidad de bytes y caracteres UTF-8 en una cadena Sybase ASE

Echemos un vistazo a las funciones para encontrar la cantidad de bytes y caracteres UTF-8 en Sybase ASE DBMS. Esta función se creó y utilizó en un proyecto que convierte la codificación no Unicode de Sybase ASE, EUC-KSC, a la codificación Unicode, UTF-8.

* Codificación UTF-8 Nota: UTF-8 – Wikipedia, la enciclopedia de todos (wikipedia.org)

Al convertir una columna declarada como varchar(10) en EUC-KSC a UTF-8, es necesario verificar el número máximo de bytes y caracteres.

Al convertir a UTF-8, la cantidad máxima de bytes y caracteres es necesaria para determinar cuánto declarar la longitud máxima de una columna de cadena. Esta función se usó para calcular el valor máximo calculando la cantidad de bytes y caracteres convertidos a la codificación UTF-8 para el valor almacenado en la codificación EUC-KSC, que no es la longitud declarada.

El DBMS se probó en Sybase ASE v15.5. No lo he probado en otras versiones, pero creo que debería funcionar.

Sybase ASE es muy similar a MS-SQL, por lo que puede usarlo sin ninguna modificación en MS-SQL.

1. Función de conteo de bytes UTF-8

IF OBJECT_ID('dbo.GET_UTF8_BYTE') IS NOT NULL
  DROP FUNCTION dbo.GET_UTF8_BYTE
GO

CREATE FUNCTION dbo.GET_UTF8_BYTE
(
    @IN_VAL VARCHAR(4000)
)
RETURNS INT
AS
BEGIN
  DECLARE @CHK_LENGTH INT, @I INT, @CHK_BYTE INT, @BYTE_LEN INT, @UTF8_BYTE_LEN INT, @SUM_UTF8_BYTE_LEN INT

  SELECT @I = 1, @CHK_LENGTH = LEN(@IN_VAL), @SUM_UTF8_BYTE_LEN = 0

  WHILE @I <= @CHK_LENGTH
  BEGIN
    SELECT @CHK_BYTE = ASCII(SUBSTRING(@IN_VAL, @I, 1))

    IF @CHK_BYTE >= 128 -- ASCII 코드가 alpha, numeric, control 문자 범위를 넘는 경우(2 Byte 문자일 경우)
        SELECT @BYTE_LEN = 2, @UTF8_BYTE_LEN = 3
    ELSE
        SELECT @BYTE_LEN = 1, @UTF8_BYTE_LEN = 1

    SELECT @SUM_UTF8_BYTE_LEN = @SUM_UTF8_BYTE_LEN + @UTF8_BYTE_LEN, @I = @I + @BYTE_LEN
  END

  RETURN @SUM_UTF8_BYTE_LEN
END
GO

Este código fue escrito en base a los siguientes hechos.

  • Si el código ASCII de 1 byte no Unicode es 128 o superior, el carácter de 2 bytes (coreano, chino, japonés, etc.)
  • El carácter no Unicode Hangul 1 (2 bytes) se almacena como 3 bytes en codificación UTF-8

La explicación del código principal es la siguiente.

  • Línea 18: Lea la cadena de entrada byte por byte.
  • Línea 21: establezca la longitud de los bytes para omitir si el código ASCII de los bytes leídos es mayor o igual a 128, aumente el número de bytes UTF-8 en 3
  • Línea 23: si el código ASCII de los bytes leídos es inferior a 128, configure la longitud de bytes para saltar a 1, incremente el número de bytes UTF-8 en 1
  • Línea 25: Acumule la suma de bytes UTF-8, incremente el valor de la variable de condición @I en el ciclo WHILE por la longitud de bytes para omitir

2. Función para encontrar el número de caracteres UTF-8

La función anterior se puede modificar de la siguiente manera para obtener la cantidad de caracteres en lugar de la cantidad de bytes UTF-8.

IF OBJECT_ID('dbo.GET_CHAR_CNT') IS NOT NULL
  DROP FUNCTION dbo.GET_CHAR_CNT
GO

CREATE FUNCTION dbo.GET_CHAR_CNT
(
    @IN_VAL VARCHAR(4000)
)
RETURNS INT
AS
BEGIN
  DECLARE @CHK_LENGTH INT, @I INT, @CHK_BYTE INT, @BYTE_LEN INT, @UTF8_BYTE_LEN INT, @SUM_UTF8_BYTE_LEN INT, @SUM_CHAR_CNT INT

  SELECT @I = 1, @CHK_LENGTH = LEN(@IN_VAL), @SUM_UTF8_BYTE_LEN = 0, @SUM_CHAR_CNT = 0

  WHILE @I <= @CHK_LENGTH
  BEGIN
    SELECT @CHK_BYTE = ASCII(SUBSTRING(@IN_VAL, @I, 1))

    IF @CHK_BYTE >= 128 -- ASCII 코드가 alpha, numeric, control 문자 범위를 넘는 경우(2 Byte 문자일 경우)
        SELECT @BYTE_LEN = 2, @UTF8_BYTE_LEN = 3
    ELSE
        SELECT @BYTE_LEN = 1, @UTF8_BYTE_LEN = 1

    SELECT @SUM_UTF8_BYTE_LEN = @SUM_UTF8_BYTE_LEN + @UTF8_BYTE_LEN, @I = @I + @BYTE_LEN
    SELECT @SUM_CHAR_CNT = @SUM_CHAR_CNT + 1
  END

  --RETURN @SUM_UTF8_BYTE_LEN
  RETURN @SUM_CHAR_CNT
END

El ciclo WHILE que comienza en la línea 16 termina con la variable @I como condición. La variable @BYTE_LEN se establece en 2 (carácter de doble byte) o 1 (carácter de un solo byte) según el código ASCII del byte leído, y se agrega a @I en la línea 25. Con esta lógica, la instrucción de bucle WHILE se ejecuta repetidamente tantas veces como el número de caracteres.

La razón por la que @SUM_CHAR_CNT se incrementa en 1 en la línea 26 es que el número de repeticiones es el número de caracteres.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

es_ESEspañol