1. Enorable
  2. Base De Datos
  3. Oracle
1
0
 
vistas: 860
Joswald Oropeza
| 16/11/2019

Validar datos con expresiones regulares en PL/SQL de Oracle

Función para validar de manera estricta los datos ingresados por un usuario a través de un formulario o cualquier otro método que permita la entrada de la información.

Como en muchos otros lenguajes de programación, PL/SQL de Oracle también permite la validación estricta de los datos que se manejan o manipulan en un programa o aplicación. Esto es posible cuando presionamos a los usuarios a ingresar única y exclusivamente la información que requiere un sistema antes de seguir avanzando.

En Oracle se permite el uso de expresiones regulares para buscar patrones dentro de las cadenas de los datos, mediante convenciones de sintaxis estandarizadas.

Al igual que en otros lenguajes, las expresiones regulares se caracterizan por la implementación de metacaracteres o de operadores que especifican un algoritmo de búsqueda, pero al mismo tiempo se combinan con caracteres de tipo literal, para indicar y profundizar en las cadenas que pretendemos encontrar durante el proceso.

Con una expresión regular se puede especificar una búsqueda mucho más compleja que la expresada por ejemplo por formato como: «999,999,999.99»; mediante un patrón que consiste en una secuencia de caracteres.

Trabajar con expresiones regulares a veces suele ser un poco complicado y frustrante, pero al mismo tiempo, se convierte en uno de los métodos más recomendados cuando requerimos validar correctamente la entrada que hace un usuario a través del sistema, y no basta con indicar que un campo sea Varchar2, Number, Decimal, Date u otro tipo para asegurar la información.

Función para validar datos con expresiones regulares

En esta ocasión he creado una básica función para Oracle, que permite realizar validaciones más complejas a través de la implementación de patrones de expresión regular.

Dicha función una vez creada en nuestra base de datos puede ser usada más adelante en cualquier proyecto que se implemente.

Para más recursos relacionados en PL/SQL de Oracle, puede apoyar mi contribución en esta categoría realizando una donación (BTC) desde su billetera digital preferida.

Creando la función F_VALIDATE_WITH_REGEXP

Esta función acepta solamente dos parámetros de entrada, los cuales son los siguientes:

  • p_str - El valor o cadena a validar
  • p_type - El tipo de patrón que usará la expresión regular para la validación

Para este ejemplo he incluído los siguientes tipos de patrones:

  • alphanumeric - Datos Alfanuméricos
  • date (dd/mm/yyyy) - Datos tipo Fecha con formato (dd/mm/yyyy)
  • date (mm-dd-yyyy) - Datos tipo Fecha con formato (mm-dd-yyyy)
  • date (yyyy-mm-dd) - Datos tipo Fecha con formato (yyyy-mm-dd)
  • date (yyyy-mm) - Datos tipo Fecha con formato (yyyy-mm)
  • date (yyyy) - Datos tipo Fecha con formato (yyyy)
  • datetime - Datos tipo Fecha con formato (yyyy-mm-dd hh:mm:ss)
  • decimal - Datos decimal
  • domain - Dominios (https://enorable.com)
  • email - Email (myemail@gmail.com)
  • http - Dirección con protocolo http o https
  • image - Datos que contengan un formato de imagen (gif, jpeg, jpg, png)
  • ipaddr - Dirección IP (192.168.200.190)
  • numeric - Datos numéricos
  • md5 - Datos de tipo hash MD5
  • sha1 - Datos de tipo hash sha1
  • sha256 - Datos de tipo hash sha256
  • onechar - Datos de un solo caracter
  • phone - Datos de tipo teléfono
  • taxinfo - Datos de tipo Tax Info o Información Tributaria
  • url - Datos de tipo URL (https://www.google.com/search?q=enorable)

NOTA: cuando los datos se vuelven aún más complejos de controlar por el sistema, es donde se requieren los servicios de las expresiones regulares.

CREATE OR REPLACE FUNCTION F_VALIDATE_WITH_REGEXP
(p_str IN VARCHAR2,
p_type IN VARCHAR2 DEFAULT 'alphanumeric')
RETURN BOOLEAN
IS
v_regexp VARCHAR2(1000) := '^([\w\s]*?)+';
v_result NUMBER := 0;
BEGIN
CASE p_type
WHEN 'alphanumeric' THEN v_regexp := '^([\w\s]*?)+';
WHEN 'date_dd/mm/yyy' THEN v_regexp := '^([0-9]{2})\/([0-9]{2})\/([0-9]{4})';
WHEN 'date_mm-dd-yyyy' THEN v_regexp := '^([0-9]{2})-([0-9]{2})-([0-9]{4})';
WHEN 'date_yyyy-mm-dd' THEN v_regexp := '^([0-9]{4})-([0-9]{2})-([0-9]{2})';
WHEN 'date_yyyy-mm' THEN v_regexp := '^([0-9]{4})-([0-9]{2})';
WHEN 'date_yyyy' THEN v_regexp := '^[0-9]{4}';
WHEN 'datetime_yyyy-mm-dd_hh:mm:ss' THEN v_regexp := '^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})';
WHEN 'decimal' THEN v_regexp := '^[-]?[0-9]+(\.[0-9]{0,2})';
WHEN 'domain' THEN v_regexp := '(^(https:|http:)\/\/(www\.)?([a-zA-Z0-9\_\-\/]+\.)(com|net|org|biz|info|xyz|online|club|dev|live|space|app|site|shop|life|io|store|tech|news|media|design|guru|photography|global|rocks|today|movie|[a-z]{2,15})?(\.)?([a-z]{2,5}))';
WHEN 'email' THEN v_regexp := '^(\w+)(\w\-\.+)?@(\w+)\.([a-z]{2,6}|es|aero|asia|arpa|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|movie|net|org|com\.ve|com\.ar|com\.co|com\.br|com\.cl|com\.mx|com\.pe|com\.uy|com\.py)';
WHEN 'http' THEN v_regexp := '^(https:|http:)';
WHEN 'images' THEN v_regexp := '([^\s]+(\.(jpe?g|png|gif|jpg)))';
WHEN 'ipaddr' THEN v_regexp := '^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})';
WHEN 'numeric' THEN v_regexp := '^[-]?[0-9]+';
WHEN 'md5' THEN v_regexp := '[a-zA-Z0-9]{32}';
WHEN 'sha1' THEN v_regexp := '[a-zA-Z0-9]{40}';
WHEN 'sha256' THEN v_regexp := '[a-zA-Z0-9]{64}';
WHEN 'onechar' THEN v_regexp := '^([a-zA-Z]){1}';
WHEN 'phone' THEN v_regexp := '^\([0-9]{1,4}\)\s([0-9]{3}\s[0-9\-]{4})';
WHEN 'taxinfo' THEN v_regexp := '^[a-zA-Z0-9\-]{1,}[a-z0-9\s\.\-]';
WHEN 'url' THEN v_regexp := '(^(https:|http:)\/\/(www\.)?([a-zA-Z0-9\_\-]+\.)(com|net|org|biz|info|xyz|online|club|dev|live|space|app|site|shop|life|io|store|tech|news|media|design|guru|photography|global|rocks|today|movie|[a-z]{2,15})?(\.)?([a-z]{2,5})([a-zA-Z0-9\%\/\?\+\-\_\=\&\#]+))';
ELSE v_regexp := '^([\w\s]*?)+';
END CASE;
SELECT REGEXP_INSTR (p_str, v_regexp)
INTO v_result
FROM DUAL;
IF v_result < 0 OR v_result = 0 THEN
RETURN FALSE;
ELSE
RETURN TRUE;
END IF;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE ('ERROR:' || ' (' || sqlcode || ') '||sqlerrm);
RETURN FALSE;
END F_VALIDATE_WITH_REGEXP;
/
Function created.

Probando la función F_VALIDATE_WITH_REGEXP

Luego de que nuestra función ya ha sido creada, procedemos entonces a probar los resultados que ésta genera a partir de una serie de datos introducidos para los diferentes tipos de patrones que hemos predefinido. Y para ello corremos el siguiente bloque anónimo:

DECLARE
v_res_alphanumeric BOOLEAN := FALSE;
v_res_date1 BOOLEAN := FALSE;
v_res_date2 BOOLEAN := FALSE;
v_res_date3 BOOLEAN := FALSE;
v_res_date4 BOOLEAN := FALSE;
v_res_date5 BOOLEAN := FALSE;
v_res_datetime BOOLEAN := FALSE;
v_res_decimal BOOLEAN := FALSE;
v_res_domain BOOLEAN := FALSE;
v_res_email BOOLEAN := FALSE;
v_res_http BOOLEAN := FALSE;
v_res_image BOOLEAN := FALSE;
v_res_ipaddr BOOLEAN := FALSE;
v_res_numeric BOOLEAN := FALSE;
v_res_md5 BOOLEAN := FALSE;
v_res_sha1 BOOLEAN := FALSE;
v_res_sha256 BOOLEAN := FALSE;
v_res_onechar BOOLEAN := FALSE;
v_res_phone BOOLEAN := FALSE;
v_res_taxinfo BOOLEAN := FALSE;
v_res_url BOOLEAN := FALSE;
BEGIN
v_res_alphanumeric := F_VALIDATE_WITH_REGEXP ('hola mundo', 'alphanumeric');
IF v_res_alphanumeric THEN
DBMS_OUTPUT.PUT_LINE('ALPHANUMERIC IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('ALPHANUMERIC IS FALSE');
END IF;
v_res_date1 := F_VALIDATE_WITH_REGEXP ('12/10/1964', 'date_dd/mm/yyyy');
IF v_res_date1 THEN
DBMS_OUTPUT.PUT_LINE('DATE1 (dd/mm/yyyy) IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('DATE1 (dd/mm/yyyy) IS FALSE');
END IF;
v_res_date2 := F_VALIDATE_WITH_REGEXP ('07-20-1972','date_mm-dd-yyyy');
IF v_res_date2 THEN
DBMS_OUTPUT.PUT_LINE('DATE2 (mm-dd-yyyy) IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('DATE2 (mm-dd-yyyy) IS FALSE');
END IF;
v_res_date3 := F_VALIDATE_WITH_REGEXP ('1980-08-18','date_yyyy-mm-dd');
IF v_res_date3 THEN
DBMS_OUTPUT.PUT_LINE('DATE3 (yyyy-mm-dd) IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('DATE3 (yyyy-mm-dd) IS FALSE');
END IF;
v_res_date4 := F_VALIDATE_WITH_REGEXP ('1994-05','date_yyyy-mm');
IF v_res_date4 THEN
DBMS_OUTPUT.PUT_LINE('DATE4 (yyyy-mm) IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('DATE4 (yyyy-mm) IS FALSE');
END IF;
v_res_date5 := F_VALIDATE_WITH_REGEXP ('1978', 'date_yyyy');
IF v_res_date5 THEN
DBMS_OUTPUT.PUT_LINE('DATE5 (yyyy) IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('DATE5 (yyyy) IS FALSE');
END IF;
v_res_datetime := F_VALIDATE_WITH_REGEXP ('1901-01-22 16:00:30','datetime_yyyy-mm-dd_hh:mm:ss');
IF v_res_datetime THEN
DBMS_OUTPUT.PUT_LINE('DATETIME (yyyy-mm-dd hh:mm:ss) IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('DATETIME (yyyy-mm-dd hh:mm:ss) IS FALSE');
END IF;
v_res_decimal := F_VALIDATE_WITH_REGEXP ('23981.98','decimal');
IF v_res_decimal THEN
DBMS_OUTPUT.PUT_LINE('DECIMAL IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('DECIMAL IS FALSE');
END IF;
v_res_domain := F_VALIDATE_WITH_REGEXP ('https://enorable.com','domain');
IF v_res_domain THEN
DBMS_OUTPUT.PUT_LINE('DOMAIN IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('DOMAIN IS FALSE');
END IF;
v_res_email := F_VALIDATE_WITH_REGEXP ('jaooauq_aa909@gmail.com','email');
IF v_res_email THEN
DBMS_OUTPUT.PUT_LINE('EMAIL IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('EMAIL IS FALSE');
END IF;
v_res_http:= F_VALIDATE_WITH_REGEXP ('https://google.com','http');
IF v_res_http THEN
DBMS_OUTPUT.PUT_LINE('HTTP IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('HTTP IS FALSE');
END IF;
v_res_image := F_VALIDATE_WITH_REGEXP ('thisistheimage.jpeg','image');
IF v_res_image THEN
DBMS_OUTPUT.PUT_LINE('IMAGE IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('IMAGE IS FALSE');
END IF;
v_res_ipaddr := F_VALIDATE_WITH_REGEXP ('192.168.0.1','ipaddr');
IF v_res_ipaddr THEN
DBMS_OUTPUT.PUT_LINE('IPADDR IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('IPADDR IS FALSE');
END IF;
v_res_numeric := F_VALIDATE_WITH_REGEXP ('-12309','numeric');
IF v_res_numeric THEN
DBMS_OUTPUT.PUT_LINE('NUMERIC IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('NUMERIC IS FALSE');
END IF;
v_res_md5 := F_VALIDATE_WITH_REGEXP ('a98sj183ydn3j4bg8du2l930spao12j4','md5');
IF v_res_md5 THEN
DBMS_OUTPUT.PUT_LINE('MD5 IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('MD5 IS FALSE');
END IF;
v_res_sha1 := F_VALIDATE_WITH_REGEXP ('a98sj183ydn3j4bg8du2l930spao12j4nj28fhr6','sha1');
IF v_res_sha1 THEN
DBMS_OUTPUT.PUT_LINE('SHA1 IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('SHA1 IS FALSE');
END IF;
v_res_sha256 := F_VALIDATE_WITH_REGEXP ('a98sj183ydn3j4bg8du2l930spao12j4nj28fhr69aj27u37dh472h182o3g72o1','sha256');
IF v_res_sha256 THEN
DBMS_OUTPUT.PUT_LINE('SHA256 IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('SHA256 IS FALSE');
END IF;
v_res_onechar := F_VALIDATE_WITH_REGEXP ('a','onechar');
IF v_res_onechar THEN
DBMS_OUTPUT.PUT_LINE('ONECHAR IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('ONECHAR IS FALSE');
END IF;
v_res_phone := F_VALIDATE_WITH_REGEXP ('(0220) 555 98-02','phone');
IF v_res_phone THEN
DBMS_OUTPUT.PUT_LINE('PHONE IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('PHONE IS FALSE');
END IF;
v_res_taxinfo := F_VALIDATE_WITH_REGEXP ('J-000099998-2','taxinfo');
IF v_res_taxinfo THEN
DBMS_OUTPUT.PUT_LINE('TAXINFO IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('TAXINFO IS FALSE');
END IF;
v_res_url := F_VALIDATE_WITH_REGEXP ('https://www.google.com/search?q=enorable&oq=enorable','url');
IF v_res_url THEN
DBMS_OUTPUT.PUT_LINE('URL IS TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE('URL IS FALSE');
END IF;
END;
Statement processed.
ALPHANUMERIC IS TRUE
DATE1 (dd/mm/yyyy) IS TRUE
DATE2 (mm-dd-yyyy) IS TRUE
DATE3 (yyyy-mm-dd) IS TRUE
DATE4 (yyyy-mm) IS TRUE
DATE5 (yyyy) IS TRUE
DATETIME (yyyy-mm-dd hh:mm:ss) IS TRUE
DECIMAL IS TRUE
DOMAIN IS TRUE
EMAIL IS TRUE
HTTP IS TRUE
IMAGE IS TRUE
IPADDR IS TRUE
NUMERIC IS TRUE
MD5 IS TRUE
SHA1 IS TRUE
SHA256 IS TRUE
ONECHAR IS TRUE
PHONE IS TRUE
TAXINFO IS TRUE
URL IS TRUE
El resultado de este código también lo puede comprobar a través de Live SQL de Oracle.

Todos los titulares en un solo lugar...