viernes, 1 de julio de 2011

Un contador de palabras iguales en PL SQL

Este procedimiento permite buscar una palabra a partir de un texto y devolver el número de ocurrencias.

El procedimiento admite dos argumentos, el primero es la cadena (texto) a evaluar y el segundo argumento es la palabra a buscar.


Puntos a tomar en cuenta:



  • Necesitamos tener una variable de tipo number que nos permita guardar el total de las palabras iguales( cont number(3) ).
  • Como PL SQL no tiene una función específica para separar palabra por palabra de una cadena, nos serviremos de las funciones count, substr e instr (más adelante veremos porqué).
  • Debemos tener en cuenta  (para casos más detallistas) por ejemplo  la palabra "Hola" es diferente a "hola", así que lo mejor es darle formato  al texto y a la palabra a buscar, en este caso, lo que yo hice fue poner todo el texto en minúsculas mediante la función lower.
  • Al punto anterior se le añade  también la diferencia por ejemplo entre "Hola." y "Hola", debido a que en la primera existe un punto final, así que debemos de tener en cuenta esos signos de puntuación (;  , . :) , así bien lo que recomiendo es tener una variable por cada caso de signo.
Manos a la obra: 

/* Creamos el bloque con los dos argumentos, el primero es la cadena (párrafo) y el segundo la palabra a buscar.
El procedimiento se llama buscador
*/

create or replace procedure buscador (parrafo in varchar, palabra in varchar)
is
cont number(3):=0; -- Inicializamos el contador a 0
token varchar2(30); -- Almaceno una palabra que termine sin ningun signo de puntuacion.
tokpc varchar2(30); --
Almaceno una palabra que termine con punto y coma.
tokpf varchar2(30); --
Almaceno una palabra que termine con punto final
tokcc varchar2(30); --
Almaceno una palabra que termine con coma
tokdp varchar2(30); --
Almaceno una palabra que termine con dos puntos

/* Almacenaremos en una variable llamada parr el párrafo y le agregaremos un espacio en blanco
   El espacio en blanco es para evitar problemas en los cursores implicitos. 
   En esta variable el parrafo se le da el formato de minúsculas.
*/
parr  varchar2(1000):=lower(parrafo)||' ';
ntoken number(2):=0; -- Para contar si todavia hay palabras en la cadena
begin

 -- Haremos un ciclo para obtener palabra por palabra del párrafo.  
LOOP
-- A partir de la consulta, obtendremos una palabra del párrafo o cadena de texto.
-- La tabla dual viene por defecto y no hay que crearla (Esta es de mucha utilidad). 
select count(substr(parr,0,(instr(parr,' ')-1)))  into ntoken from dual;
 -- Si hay palabras  disponibles,entonces entra al if; de lo contrario saliir del ciclo.
   if ntoken > 0 then
-- Obtenemos cualquier palabra que pueda contener algún o ningún signo de puntuación
    select substr(parr,0,(instr(parr,' ')-1)) into token from dual;
     select substr(parr,0,(instr(parr,'. ')-1)) into tokpf from dual;
     select substr(parr,0,(instr(parr,'; ')-1)) into tokpc from dual;
     select substr(parr,0,(instr(parr,', ')-1)) into tokcc from dual;
     select substr(parr,0,(instr(parr,': ')-1)) into tokdp from dual

-- Comparamos si las palabras obtenidas son iguales a la palabra a buscar
-- En caso de ser cierto, incrementamos el contador.
    if token=palabra or tokpc=palabra or tokcc=palabra or tokpf=palabra or tokdp=palabra then
       cont:=cont+1;
     end if;

-- Aquí simulamos avanzar a la palabra siguiente descartando la palabra anterior.
 select substr(parr,(instr(parr,' ')+1)) into parr from dual;  

else 
  -- Salir de ciclo
  exit; 

end if; 
END LOOP;
DBMS_output.put_line('Palabras encontradas: '||cont);
end;
/


Resultados:

Llamaremos a nuestro procedimiento mediante la instrucción exec y los cuatro ejemplos deben devolver 4 palabras encontradas, las palabras en este color representan la cadena de texto y las que tienen este color, representan la cadena a buscar .
 
exec buscador('Uno. uno dos uno.','uno');
exec buscador('Dos; dos tres dos; ','dos');
exec buscador('Tres: TrEs cuatro tres','tres');
exec buscador('Cuatro, cuaTro cinco, CuATRo','cuatro');





Detalles:
  • La intstrucción count ( ) la utilizamos para verificar si aún podemos obtener alguna palabra del párrafo o cadena de texto.
  •  La instrucción substr ( )  nos ayuda a obtener una cadena, en este caso la combino con la función instr( ) que nos devuelve el índice del primer elemento (que coincida en su segundo argumento) para obtener el límite de una palabra y así obtener una palabra completa.
  • Así también uso las dos últimas funciones para descartar la palabra que hemos comparado y avanzar a una nueva.