A veces necesitamos verificar que el e-mail que el usuario introdujo sea un e-mail válido, es decir que cumpla con las reglas para ser usado como tal.

¿Cómo lo validamos?

Bien, hay varias formas de hacerlo pero probablemente la más inteligente sea usando expresiones regulares.  Mediante una expresión regular comparamos un string cualquiera con un patrón de caracteres. El resultado de esa comparación puede ser verdadero o falso, desde luego.

Entonces, para validar un e-mail usando expresiones regulares podríamos escribir algo como:

SELECT
   IIF('minombre@midominio.com' SIMILAR TO '[[:ALNUM:]-_.]*@[[:ALNUM:]-_.]*', 'válido', 'no válido')
FROM
   RDB$DATABASE

El e-mail que queremos validar es minombre@midominio.com y para ello en el SELECT usamos SIMILAR TO. Al usar SIMILAR TO le estamos diciendo al Firebird que usaremos una expresión regular.

¿Y qué significa todo lo que está a continuación de SIMILAR TO?

:ALNUM: es la abreviación de alfanumérico, es decir que incluye todos los caracteres desde la ‘a’ hasta la ‘z’, desde la ‘A’ hasta la ‘Z’ y desde el ‘0’ hasta el ‘9’.

* significa que el caracter precedente puede encontrarse 0 ó muchas veces

@ significa que sí o sí debe existir el carácter @ en esa posición

[] significa que es una clase, o sea cualquiera de los miembros de esa clase pueden existir

Entonces, en castellano lo que dice esa expresión regular es: “Cualquier carácter alfanumérico, el guión, el guión bajo y el punto, pueden repetirse entre cero y muchas veces. El símbolo de arroba debe existir, es obligatorio. Y luego cualquier carácter alfanumérico, el guión, el guión bajo y el punto, pueden repetirse entre cero y muchas veces.”

Entonces, ahora nos falta verificar que realmente con esa expresión regular podemos validar e-mails, así que probamos con varios de ellos, como:

‘minombre@midominio.com’

‘MiNombre@MiDominio.com’

‘MiNombre123@MiDominio.com’

‘Mi_Nombre_123@Mi_Dominio.com’

‘Mi_Nombre_123@Mi_Dominio.com.py’

Y vemos que con todos ellos funciona perfectamente. Así que ahora probamos con e-mails que sabemos inválidos, como los siguientes:

‘minombremidominio’

‘minombremidominio.com’

‘.com’

Y vemos que efectivamente son rechazados.

Bien, la validación no es perfecta ya que acepta los siguientes e-mails:

‘@com’

‘@.com’

Pero de todas maneras es de una gran ayuda y simple de escribir. Hay varias formas de validar que no empiece con @, una de ellas es la siguiente:

SELECT
   IIF('@com' SIMILAR TO '[[:ALNUM:]-_.]*@[[:ALNUM:]-_.]*' and
       SUBSTRING('@com' FROM 1 FOR 1) <> '@', 'válida', 'no válida')
FROM
   RDB$DATABASE

Donde lo que hacemos es verificar que el primer carácter no sea una @. Desde luego que en general no estarás validando contra una constante de tipo string sino contra una columna. Por ejemplo para usarlo en un trigger podrías escribir algo como:

CREATE EXCEPTION E_EMAIL_NO_VALIDO 'El e-mail no es válido, verifícalo.';
CREATE TRIGGER BIU_CLIENTES FOR CLIENTES
   ACTIVE BEFORE INSERT OR UPDATE
   POSITION 1
AS
   DECLARE VARIABLE lcEmailOK CHAR(1);
BEGIN

   lcEmailOK = (SELECT
                   IIF(NEW.CLI_EMAILX
                   SIMILAR TO '[[:ALNUM:]-_.]*@[[:ALNUM:]-_.]*' AND
                   SUBSTRING(NEW.CLI_EMAILX FROM 1 FOR 1) <> '@', 'T', 'F')
                FROM
                   RDB$DATABASE);

   IF (lcEmailOK = 'F') THEN
      EXCEPTION E_EMAIL_NO_VALIDO;

END;

La gran mayoría de los usuarios si escriben mal un e-mail es porque se equivocaron al hacerlo, no por maldad sino por una equivocación humana. Para detectar algunas de esas equivocaciones podríamos mejorar un poco el trigger anterior, que ahora quedaría así:

CREATE TRIGGER BIU_CLIENTES FOR CLIENTES
   ACTIVE BEFORE INSERT OR UPDATE
   POSITION 0
AS
   DECLARE VARIABLE lcEmailOK CHAR(1);
BEGIN

   lcEmailOK = (SELECT
                   IIF(NEW.CLI_EMAILX
                   SIMILAR TO '[[:ALNUM:]-_.]*@[[:ALNUM:]-_.]*' AND
                   SUBSTRING(NEW.CLI_EMAILX FROM 1 FOR 1) <> '@', 'T', 'F')
                FROM
                   RDB$DATABASE);
   
   IF (lcEmailOK = 'T') THEN
      lcEmailOK = IIF(NEW.CLI_EMAILX CONTAINING '--', 'F', lcEmailOK);
   
   IF (lcEmailOK = 'T') THEN
      lcEmailOK = IIF(NEW.CLI_EMAILX CONTAINING '__', 'F', lcEmailOK);
   
   IF (lcEmailOK = 'T') THEN
      lcEmailOK = IIF(NEW.CLI_EMAILX CONTAINING '..', 'F', lcEmailOK);
   
   IF (lcEmailOK = 'F') THEN
      EXCEPTION E_EMAIL_NO_VALIDO;

END;

Donde lo que hacemos es verificar que no haya escrito dos guiones seguidos, dos guiones bajos seguidos, o dos puntos seguidos. Ninguna de esas posibilidades es normalmente usada en un e-mail, así que las rechazamos. Desde luego que podrías agregar otras comparaciones si te parecen necesarias.

Y de esta manera siempre que el usuario esté intentando insertar o actualizar los datos de un cliente se verificará que el e-mail de ese cliente sea un e-mail que cumple con las reglas mínimas para ser admitido como tal. Si no las cumple entonces se lanzará una excepción informándole del problema.

Artículos relacionados:

Los predicados de comparación

Usando SIMILAR TO

El índice del blog Firebird21

El foro del blog Firebird21