Verificando si un string es un número válido

2 comentarios

A veces podemos necesitar saber si en una columna de tipo CHAR o VARCHAR se ha guardado un número válido.

¿Cómo lo conseguimos rápidamente?

Usando el predicado de comparación SIMILAR TO.

Ejemplo 1:

En la tabla de ALUMNOS tenemos una columna donde guardamos el número de la matrícula. Queremos verificar que solamente haya números válidos allí.

NUMEROS1

Captura 1. Si haces clic en la imagen la verás más grande

Listado 1.

SELECT
   ALU_MATRIC,
   ALU_NOMBRE
FROM
   ALUMNOS
WHERE
   ALU_MATRIC SIMILAR TO '[0-9]*'

NUMEROS2

Captura 2. Si haces clic en la imagen la verás más grande

Ejemplo 2:

Queremos saber cuales son los alumnos cuyo número de matrícula es incorrecto. Para ello solamente agregamos NOT, como podemos ver en el Listado 2.

Listado 2.

SELECT
   ALU_MATRIC,
   ALU_NOMBRE
FROM
   ALUMNOS
WHERE
   ALU_MATRIC NOT SIMILAR TO '[0-9]*'

NUMEROS3

Captura 3. Si haces clic en la imagen la verás más grande

Si lo que nos interesa es saber cuantos alumnos tienen número de matrícula correcto o número de matrícula incorrecto entonces en lugar de seleccionar la Matrícula y el Nombre usaríamos la función agregada COUNT().

Ejemplo 3:

En la tabla FACTURAS tenemos datos de las Facturas de venta.

NUMEROS4

Captura 4. Si haces clic en la imagen la verás más grande

Por alguna razón que no sabemos, la columna FAC_COBRAD es de  tipo VARCHAR, no es numérica. Por eso ahora queremos verificar que todos los números allí escritos sean números válidos.

Listado 3.

SELECT
   FAC_NUMERO,
   FAC_FECVEN,
   FAC_COBRAD
FROM
   FACTURAS
WHERE
   TRIM(FAC_COBRAD) SIMILAR TO '[\+\-]?[0-9]*.?[0-9]*' ESCAPE '\'

NUMEROS5

Captura 5. Si haces clic en la imagen la verás más grande

Explicando el patrón usado en SIMILAR TO

NUMEROS6

Conclusión:

Saber si en una columna de tipo CHAR o VARCHAR hay solamente números válidos puede ser muy útil muchas veces, en este artículo se mostró una técnica para realizar esa verificación.

Artículos relacionados:

Los predicados de comparación

Usando SIMILAR TO

El índice del blog Firebird21

El foro del blog Firebird21

 

Los predicados de comparación

2 comentarios

Una de las principales utilidades del comando SELECT es realizar búsquedas en las tablas, así podremos saber si algún dato existe o no existe en ellas. Cuando necesitamos realizar búsquedas podemos emplear varios predicados de comparación, ellos son:

  • BETWEEN … AND …
  • CONTAINING
  • IN
  • LIKE
  • STARTING WITH
  • SIMILAR TO

BETWEEN … AND …

El predicado de comparación BETWEEN … AND … debe recibir dos argumentos (que sean de tipos compatibles) y devuelve como resultado las filas que contienen esos valores o cualquier valor incluido entre ellos. Ejemplo:

SELECT
   CLI_NOMBRE
FROM
   CLIENTES
WHERE
   CLI_CODIGO BETWEEN 1 AND 100

Este SELECT devolverá los nombres de todos los clientes cuyos códigos se encuentren entre 1 y 100, inclusives.

CONTAINING

El predicado de comparación CONTAINING busca dentro de una columna alfanumérica los caracteres pedidos. Importante: no distingue entre mayúsculas y minúsculas. Ejemplo:

SELECT
   CLI_NOMBRE
FROM
   CLIENTES
WHERE
   CLI_NOMBRE CONTAINING 'MAR'

 Este SELECT devolverá los nombres de todos los clientes que tengan los caracteres ‘MAR’ en la columna CLI_NOMBRE. Así, podríamos tener a: MARÍA TERESA, CLAUDIA MARCELA, ROSEMARY, María Estela, Ana María, Tamara, etc.

IN

El predicado de comparación IN es una forma simplificada de escribir el operador de comparación OR, los resultados obtenidos serán los mismos pero se escribe menos.

SELECT
   CLI_NOMBRE
FROM
   CLIENTES
WHERE
   CLI_CODIGO IN (15, 21, 45)

Este SELECT nos devolverá los nombres de los clientes cuyos códigos sean 15, 21, ó 45. Podríamos haberlo escrito así:

SELECT
   CLI_NOMBRE
FROM
   CLIENTES
WHERE
   CLI_CODIGO = 15 OR
   CLI_CODIGO = 21 OR
   CLI_CODIGO = 45

Como puedes ver, al usar el predicado de comparación IN se escribe mucho menos. Y cuanto mayor sea la cantidad de valores a evaluar mayor será lo que se ahorrará. Por lo tanto, si todos los valores serán comparados contra una misma columna (como en los dos ejemplos anteriores) entonces lo más conveniente siempre es usar el predicado IN y no el operador OR. Imagínate todo lo que te ahorrarás de escribir si los valores a comparar no fueran 3 como en estos ejemplos sino 20.

LIKE

El predicado de comparación LIKE tiene cuatro características muy importantes:

  1. Distingue entre mayúsculas y minúsculas
  2. Utiliza patrones de caracteres
  3. Solamente usa índices cuando no empieza con un comodín
  4. Si alguno de los valores es NULL, entonces devuelve NULL

Dentro de los patrones de caracteres podemos usar “comodines”. Ellos son:

‘%’      equivale a cualquier string, de cualquier longitud

‘_’      equivale a un solo caracter

También puede usar un caracter de escape. ¿Qué es un caracter de escape? Un caracter que le dice al Firebird que busque también al caracter que se encuentra a continuación, y lo usaríamos cuando en nuestra búsqueda queremos hallar también a los comodines % y _. Si no existiera el caracter de escape entonces no habría forma de buscar a esos dos caracteres. Ejemplos:

CLI_NOMBRE LIKE 'MAR%'                  -- Devolverá los nombres de todos los clientes que empiecen con MAR
CLI_NOMBRE LIKE 'JULI_'                 -- Devolverá los nombres de todos los clientes que tengan 5 caracteres y los cuatro primeros sean JULI
CLI_NOMBRE LIKE '%MAR%'                 -- Devolverá los nombres de todos los clientes que tengan MAR dentro suyo
PRD_NOMBRE LIKE '%A\_B%' ESCAPE '\'     -- Devolverá todos los nombres de productos que contienen A_B
PRD_NOMBRE LIKE '%\_%' ESCAPE '\'       -- Devolverá todos los nombres de productos que tienen un guión bajo

En el primer y en el segundo casos se usará un índice (si hay uno disponible, por supuesto) porque el patrón de caracteres no empieza con un comodín. En los restantes casos, nunca se usará un índice, porque empiezan con un comodín.

STARTING WITH

El predicado de comparación STARTING WITH es muy parecido a LIKE y se lo puede utilizar cuando se conocen los primeros caracteres del string buscado.

SELECT
   CLI_NOMBRE
FROM
   CLIENTES
WHERE
   CLI_NOMBRE STARTING WITH 'MAR'

Este SELECT nos traerá a MARIA TERESA, MARTHA, MARCELA, MARLENE, etc. O sea, todos los nombres que empiezan con MAR.

SIMILAR TO

El predicado de comparación SIMILAR TO también es parecido a LIKE pero nos permite escribir condiciones más complejas.

SELECT
   CLI_NOMBRE
FROM
   CLIENTES
WHERE
   CLI_NOMBRE SIMILAR TO '[CS]%'

Este SELECT nos devolverá los nombres de todos los clientes que empiecen con C o con S.

SELECT
   CLI_NOMBRE
FROM
   CLIENTES
WHERE
   CLI_NOMBRE SIMILAR TO '[CS]%a'

Este SELECT nos devolverá los nombres de todos los clientes que empiecen con C o con S y que terminen con a.

Artículos relacionados:

Los predicados existenciales

El índice del blog Firebird21

 

Ejemplo Nº 052 – Comparando strings

Deja un comentario

Cuando comparamos strings el resultado puede no ser el que esperábamos si es que no lo hacemos bien.

Ejemplo:

SELECT
   1
FROM
   RDB$DATABASE
WHERE
   'A' = 'A      '

Este SELECT devolverá 1 aunque los strings son diferentes. ¿Es eso correcto o incorrecto? Pues es lo correcto según el estándar SQL el cual dice lo siguiente: “cuando se comparan strings de distinta longitud, la comparación debe ser hecha como si al string más corto se le agregaran espacios en blanco hasta la longitud del string más largo”.

¿Y si queremos que la condición no se cumpla cuándo las longitudes son diferentes?

En ese caso deberemos utilizar LIKE, como vemos a continuación:

SELECT
   1
FROM
   RDB$DATABASE
WHERE
   'A' LIKE 'A   '

Aquí el resultado de la consulta será un conjunto vacío porque la condición no se cumple.

Conclusión:

Si quieres que la comparación entre dos strings sea estricta (o sea que sean idénticos y que tengan la misma longitud) debes usar el operador LIKE, no el símbolo =

Artículo relacionado:

El índice del blog Firebird21