Translate

viernes, 22 de junio de 2012

Otra forma de escribir SQL



Es muy comun ver Sql embebido en codigo de la siguiente forma:

sql:=
  'select cmp.fecha,cmp.cliente from comprobantes cmp left join movimientos mov '+
  'on nmov.comprobante=cmp.comprobante left join clientes cli on cli.cliente=cmp.cliente '+
  'left join articulos art on art.articulo=mov.articulo left join comprobantesimpuestos cim on '+
  'cim.comprobante=cmp.comprobante '+
  'where cmp.fecha between '+QuotedStr(datetostr(fechadesde))+' and '+QuotedStr(datetostr(fechahasta))+' and '+
  'cli.cliente='+inttostr(cliente)

Los dos problemas que presenta esta forma de embeber sql en codigo, aparte de lo puramente estetico, son:

Es dificil de leer el sql .. o sea entender que hace.
La asignacion de valores de parametros exige la conversion en cada caso y es facil equivocarse. Por ejemplo las fechas deben ser convertidas y colocadas entre comillas.

Es posible escribir SQL embebido de una manera mejor ?

Si .. pero como ?

Una vez un gran programador me djo .. 'no te preocupes por el como sino por el que'

Por lo tanto empezemos por el 'que'. Imaginemos una clase que se dedique a construir un texto SQL ..

with TTextoDeSql.Create([
  'SELECT',
    'CMP.FECHA,',
    'CMP.CLIENTE',
  'FROM',
    'COMPROBANTES CMP',
  'LEFT JOIN',
    'MOVIMIENTOS MOV ON MOV.COMPROBANTE=CMP.COMPROBANTE',
  'LEFT JOIN',
    'CLIENTES CLI ON CLI.CLIENTE=CMP.CLIENTE',
  'LEFT JOIN',
    'ARTICULOS ART ON ART.ARTICULO=MOV.ARTICULO',
  'LEFT JOIN',
    'COMPROBANTESIMPUESTOS CIM ON CIM.COMPROBANTE=CMP.COMPROBANTE',
  'WHERE',
    'CMP.FECHA BETWEEN @DESDE AND @HASTA AND',
    'CMP.CLIENTE=@CLIENTE ']) do
try
  Parametro('DESDE',dFechaDesde);
  Parametro('HASTA',dFechaHasta);
  Parametro('CLIENTE',nCliente);
  Result:=Texto;
finally
  Free;
end;

Es mas legible no ? ...  No solo eso, la clase TTextoDeSql, se ocupara de transforma los valores asignados a los distintos parametros en literales validos para una sentencia SQL, sin que hay que preocuparse por comillas, conversiones, concatencion y demas.

3 comentarios:

  1. No me quedó muy claro, ¿tienes el código completo de esta clase? Por ejemplo, qué haceel procedimiento Parametro, de donde salen los dFechaDesde, nCliente, etc?

    ResponderEliminar
  2. Hola, no encuentro esa clase....
    ¿ Tienes el codigo de esa clase ? O un enlace ?

    ResponderEliminar
  3. Hola, no encuentro esa clase....
    ¿ Tienes el codigo de esa clase ? O un enlace ?

    ResponderEliminar