sábado, 26 de mayo de 2012

SQL Parser

Para aquellos que necesiten un sql parser.
Con este codigo se pueden extraer los privilegios y los objetos.


 Les paso uno hecho en SL.
Ejemplo: sql_examples.sql
select * from tabla1;
select *
  from tabla2
 where columna1=1;
 select columna1,columna2
    ,columna3
  from tabla3;
select columna1, (select columna1 from tabla4) as columna2
  from tabla5 tab
 where exists (select 1 from tabla6 tab6 where tab.columna1 = tab6.columna3);

update tabla7 set columna1 = 1000;
delete from tabla8;
insert into tabla9 (columna1) values (1);
insert into tabla10 values (1,2,3);
-----------------------------
------ sql_parser.sl   -----
-----------------------------
var
 linea       ="";
 cant_lineas    = 0;
 nro_caracteres = 0;
 v_caracter     = "";
 v_palabra     = "";
 cant_palabra_reservada = 0;
 line_indice    = 0;
const
 ARCH_ENTRADA  = "sql_examples.sql";
 ARCH_SALIDA  = "object.txt";
inicio
 si ( not set_stdin (ARCH_ENTRADA) ) {
  imprimir ("\nNo se pudo abrir el archivo "+ ARCH_ENTRADA);
  terminar ("\nEl programa no puede continuar.");
 }
 set_ifs ("\n");
 si ( not set_stdout (ARCH_SALIDA) ) {
  terminar ("\nNo se pudo abrir el archivo "+ ARCH_SALIDA);
 }
 leer (linea);
 mientras ( not eof() ) {
  linea=upper(linea);
  nro_caracteres=strlen(linea);
  desde line_indice= 1 hasta nro_caracteres {
   v_caracter = substr(linea,line_indice,1);
   si ( v_palabra=='(SELECT') { v_palabra = 'SELECT';}
   si ( es_delimitador_sr(v_caracter) ) {
    si ( es_privilegio_sr(v_palabra) ) {
   v_palabra = substr(lpad(' ', (cant_palabra_reservada - 1) * 3, '- ') + v_palabra, 1, 60);
     imprimir("\n",v_palabra);
    }
 si ( cant_palabra_reservada > 0 ) {
   v_palabra = substr(lpad(' ', (cant_palabra_reservada - 1) * 3, '- ') + v_palabra, 1, 60);
     imprimir("\n",v_palabra);
     dec(cant_palabra_reservada);
    }
 si ( es_palabra_clave_sr(v_palabra) ) {
     inc(cant_palabra_reservada);
 }
    v_palabra = "";
   sino
    v_palabra = v_palabra+v_caracter;
   }
  }
  leer(linea);
 }
 set_stdout("");
fin;
subrutina es_privilegio_sr(p_palabra : cadena)  retorna logico
var
 es_privilegio  : logico;
 privilegios  : vector [4] cadena;
 priv_indice  : numerico;
inicio
 privilegios = {'SELECT','INSERT','UPDATE','DELETE'};
 desde priv_indice= 1 hasta alen(privilegios) {
  si (p_palabra == privilegios[priv_indice]) {
   es_privilegio = SI;
   priv_indice = alen(privilegios);
  sino
   es_privilegio = NO;
  }
 }
 retorna ( es_privilegio );
fin;
subrutina es_delimitador_sr(p_caracter : cadena)  retorna logico
var
 es_delimitador : logico;
 delimitadores  : vector [5] cadena;
 deli_indice  : numerico;
inicio
 delimitadores = {';','/',')',',',' '};
 desde deli_indice= 1 hasta alen(delimitadores) {
  si ( p_caracter == delimitadores[deli_indice] ) {
   es_delimitador = SI;
   deli_indice=alen(delimitadores);
  sino
   es_delimitador = NO;
  }
 }
 retorna ( es_delimitador );
fin;
subrutina es_palabra_clave_sr(p_clave : cadena)  retorna logico
var
 es_palabra_clave  : logico;
 palabra_clave   : vector [3] cadena;
 plcl_indice   : numerico;
inicio
 palabra_clave = {'UPDATE','FROM','INTO'};
 desde plcl_indice= 1 hasta alen(palabra_clave) {
  si (p_clave == palabra_clave[plcl_indice]) {
   es_palabra_clave = SI;
   plcl_indice = alen(palabra_clave);
  sino
   es_palabra_clave = NO;
  }
 }
 retorna ( es_palabra_clave );
fin;
subrutina lpad(p_palabra:cadena; p_cantidad :numerico; p_caracter_rellenar: cadena) retorna cadena
var
 indice      : numerico;
 v_cant_caracteres  : numerico;
inicio
 v_cant_caracteres = strlen(p_palabra);
 desde indice = 1 hasta p_cantidad - v_cant_caracteres {
  p_palabra = p_caracter_rellenar+p_palabra;
 }
 retorna p_palabra;
fin;

-----------------------------
------ object.txt   --------
-----------------------------

 SELECT
 TABLA1
 SELECT
 TABLA2
 SELECT
 TABLA3
 SELECT
 SELECT
 TABLA4
 TABLA5
 SELECT
 TABLA6
 UPDATE
 DELETE
 TABLA8
 INSERT
 TABLA9
 INSERT
 TABLA10

Ojala que les sirva.