sábado, 24 de noviembre de 2007

Migrando Stored Procedures a Groovy

Confiezo uno de mis mayores pecados: fui fanático de los Procedimientos Almacenados (stored procedures) en entornos de base de datos, eso fue hasta el año 2001 debido a las críticas no solamente de los autores sino de los gerentes de sistemas con los que trabajaba. De hecho abandonar dicha técnica fue una obligación, ya que un sistema que tube que mantener por 18 meses no los utilizaba (había una prohibición expresa) y tampoco utilizaba vistas !!!.

Había una razón muy importante para ello, el software funcionaba con tres sistemas bases de datos diferentes: Oracle, SqlServer e Interbase según las disponibilidad de cada una de los 43 empresas donde funcionaba el sistema. En tal caso como programador me tocó desempolvar mis conocimientos de estructuras de datos y familiarizarme con UML.

Hoy no voy a detallar los pros y contras de desarrollar con Procedimientos almacenados. Pero si les voy a contar que hace unos meses tube que migrar rápidamente una base de datos a estructuras en memoria construídas con C#. Habían algunos miles de líneas en TransactSql, las que debían ser analizadas cuidadosamente unas veces para mantener la misma lógica y otras para corregirla.

La manera más rápido de hacerlo fue analizar los Cursores, pero no con SQL Server, sino con Groovy.

Los cursores son la razón de ser los lenguajes almacenados.

Miremos la porción de código en TransactSql:

  1  .
  2  .
  3  .
  4  set @anio = 2007
  5  
  6  declare MICURSOR cursor for
  7      select
  8          p.PVEHAMOD as anio_modelo,
  9          c.CVEHCATV as cod_categoria_v,
 10          p.PVEHFECO as fe_co
 11      from
 12          CVEH c,
 13          PVEH p
 14      where
 15              c.CVEHCATV = p.CVEHCATV
 16          and p.PVEHANIO = @anio
 17  
 18  for each row in MICURSOR {
 19      // ...
 20      // manejar cada registro del cursor
 21      // ...
 22  }
 23  .
 24  .
 25  .

Y ahora analicemos el equivalente en Groovy ...

  1  .
  2  .
  3  .
  4  int anio = 2007
  5  
  6  String mainSql = """
  7      select
  8          p.PVEHAMOD as anio_modelo,
  9          c.CVEHCATV as cod_categoria_v,
 10          p.PVEHFECO as fe_co
 11      from
 12          CVEH c,
 13          PVEH p
 14      where
 15           c.CVEHCATV = p.CVEHCATV
 16          and p.PVEHANIO = $anio """
 17  
 18  db.eachRow(mainSql) { rec ->
 19      // ...
 20      // manejar cada registro en la variable rec
 21      // ...
 22  }
 23  .
 24  .
 25  .

Esta estructura simple me permitió extraer la lógica desde unos fuentes en SQL Server para colocarla con mejoras en lenguaje C# y trabajar sobre eficientes tablas texto. Al final de cuentas el problema era matemático y no transaccional sobre base de datos.