Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-12-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is online now
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cómo usar variables en lugar de campos

Hola, tengo una duda con la sintaxis sql en firebird, concretamente para los triggers, aunque supongo que será igual para "store procedure".

Explico el problema con un ejemplo:

Tabla....: tbSaldosApuntes
Campos...: debe1,haber1,debe2,haber2,debe3,haber3, ... debe12,haber12
Trigger..:

Código SQL [-]
declare variable iMes integer;

select 'debe'||cast(iMes as varchar2) from tbsaldosapuntes where...


Es sólo un ejemplo, pero más o menos es lo que quiero conseguir, no tener que repetir algo porque cambia sólo el número (de mes, en este caso).

Creo que se entiende.

Me parece recordar que en algún hilo se habló sobre ese tema y que era posible hacerlo, pero no lo he encontrado.

Gracias y...
Responder Con Cita
  #2  
Antiguo 18-12-2010
celades1 celades1 is offline
Miembro
 
Registrado: ago 2005
Posts: 116
Poder: 19
celades1 Va por buen camino
Hola

A partir de firebird 2.0 tienes el execute statement
yo lo utilizo para solucionar problemas parecido al que planteas



Código SQL [-]
CREATE PROCEDURE NEW_PROCEDURE 
returns (debe double precision)
as
declare variable imes integer;
declare variable cadena varchar(500);
begin
 imes=1;
  while (:imes<13) do begin
  cadena='select debe'||cast(imes as varchar(12))||' from tbsaldosapuntes'||
  ' where lo que sea' 
  execute statement cadena into :debe;
  suspend;
  imes=:imes+1;
  end
end


Saludos
Responder Con Cita
  #3  
Antiguo 18-12-2010
Avatar de Luis M.
[Luis M.] Luis M. is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Ripollet - Barcelona
Posts: 212
Poder: 20
Luis M. Va por buen camino
Hola.
No se si te servirá esto, yo lo utilizo para saber la última línea de un detalle de una tabla cualquiera, según el parámetro que le paso.

Código Delphi [-]
SET TERM ^ ;

create or alter procedure ULTIMA_LINEA (
    CAMPO_LINEA varchar(15),
    TABLA varchar(15),
    CAMPO_DOCU varchar(15),
    NUMERO_DOCU varchar(15))
returns (
    ULTIMA varchar(10))
as
begin
  /* Procedure Text */
  EXECUTE STATEMENT 'SELECT max('||:campo_linea||') FROM '||:tabla||' where '
                    ||:campo_docu||' = '||:numero_docu INTO :ultima;
  suspend;
end^

SET TERM ; ^

GRANT EXECUTE ON PROCEDURE ULTIMA_LINEA TO SYSDBA;

Un saludo.
Responder Con Cita
  #4  
Antiguo 18-12-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is online now
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Muchísimas gracias, me habéis salvado de un montón de horas de trabajo repetitivo y pesado.
Todos los días se aprende algo, voy a probarlo ahora mismo...
Responder Con Cita
  #5  
Antiguo 18-12-2010
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: dic 2003
Ubicación: Zamudio
Posts: 1.408
Poder: 22
fjcg02 Va camino a la fama
Aunque ya te han contestado ( y muy bien por cierto), yo suelo utilizar consultas de este tipo, que me han proporcionado muchas satisfacciones ante mis clientes.
Tienes meses, trimestres o lo que quieras.
Lógicamente, hay que preparar las agrupaciones, filtrar por fechas, ... pero el esqueleto es más que aprovechable. Y dándole una vuelta, se pueden conseguir resultados muy chulos.

Código SQL [-]
select
SUM(case when extract(month from loga) = 1 then PRIMARECIBO else 0 end) AS ENERO,
SUM(case when extract(month from loga) = 2 then PRIMARECIBO else 0 end) AS FEBRERO,
SUM(case when extract(month from loga) = 3 then PRIMARECIBO else 0 end) AS MARZO,
SUM(case when extract(month from loga) = 4 then PRIMARECIBO else 0 end) AS ABRIL,
SUM(case when extract(month from loga) = 5 then PRIMARECIBO else 0 end) AS MAYO,
SUM(case when extract(month from loga) = 6 then PRIMARECIBO else 0 end) AS JUNIO,
SUM(case when extract(month from loga) = 7 then PRIMARECIBO else 0 end) AS JULIO,
SUM(case when extract(month from loga) = 8 then PRIMARECIBO else 0 end) AS AGOSTO,
SUM(case when extract(month from loga) = 9 then PRIMARECIBO else 0 end) AS SEPTIEMBRE,
SUM(case when extract(month from loga) = 10 then PRIMARECIBO else 0 end) AS OCTUBRE,
SUM(case when extract(month from loga) = 11 then PRIMARECIBO else 0 end) AS NOVIEMBRE,
SUM(case when extract(month from loga) = 12 then PRIMARECIBO else 0 end) AS DICIEMBRE,
SUM(case when
          (extract(month from loga) >= 1 AND extract(month from loga) <= 3)
          then PRIMARECIBO else 0 end) AS TRIMESTRE1,
SUM(case when
          (extract(month from loga) >= 4 AND extract(month from loga) <= 6)
          then PRIMARECIBO else 0 end) AS TRIMESTRE2,
SUM(case when
          (extract(month from loga) >= 7 AND extract(month from loga) <= 9)
          then PRIMARECIBO else 0 end) AS TRIMESTRE3,
SUM(case when
          (extract(month from loga) >= 10 AND extract(month from loga) <= 12)
          then PRIMARECIBO else 0 end) AS TRIMESTRE4

from  RECIBO

Un saludo
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
Responder Con Cita
  #6  
Antiguo 18-12-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is online now
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Gracias, muy interesante.
Responder Con Cita
  #7  
Antiguo 18-12-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is online now
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Pues he estado probando y no me funciona, no sé si no vale para los triggers, aunque no da error ninguno, simplemente no se ejecuta.
He probado a guardar la sentencia creada en una tabla tbDebug y es correcta, así que no lo entiendo porque el código "normal" sí que funciona, lo he puesto al final, en comentario.
¿Podéis hacer una pruebecita con triggers en lugar de store procedure?
Estoy usando firebird 2.1

Código SQL [-]
CREATE OR ALTER trigger tbapuntes_ai0 for tbapuntes
active after insert position 0
AS
  declare variable iMes integer;
  declare variable cCampoDebe  varchar(8);
  declare variable cCampoHaber varchar(8);
  declare variable cSql        varchar(1024);
begin
  /* actualizar tbSaldosCuentas */
  if (new.codigoborrador>0) then  /* es borrador */
  begin
    update tbSaldosCuentas
    set debetotal=debetotal+new.debe,
        habertotal=habertotal+new.haber
    where codigoempresa=codigoempresa
    and ejercicio=ejercicio
    and codigocuenta=codigocuenta;
  end
  else /* no es borrador, es definitivo */
  begin
    iMes = extract(month from new.fechaasiento);
    cCampoDebe  = 'debe'  || cast(iMes as varchar(2));
    cCampoHaber = 'haber' || cast(iMes as varchar(2));
    cSql = 'update tbsaldoscuentas ' ||
           'set debetotal=debetotal+new.debe, ' ||
           'habertotal=habertotal+new.haber, ' ||
           cCampoDebe  || '=' || cCampoDebe  || '+new.debe, ' ||
           cCampoHaber || '=' || cCampoHaber || '+new.haber ' ||
           'where codigoempresa=codigoempresa ' ||
           'and ejercicio=ejercicio ' ||
           'and codigocuenta=codigocuenta';
/* >>> debug >>> */
/* insert into tbdebug (texto) values (:csql); */
/* <<< debug <<< */
    execute statement cSql;
  end

/* esto funciona */
/*
    update tbsaldoscuentas
    set debetotal  = debetotal  + new.debe,
        habertotal = habertotal + new.haber,
        debe12  = debe12  + new.debe,
        haber12 = haber12 + new.haber
    where codigoempresa=codigoempresa
    and ejercicio=ejercicio
    and codigocuenta=codigocuenta;
*/
end
Responder Con Cita
  #8  
Antiguo 19-12-2010
celades1 celades1 is offline
Miembro
 
Registrado: ago 2005
Posts: 116
Poder: 19
celades1 Va por buen camino
Hola

Creo que el problema es que no tratas los new como variables

csql todo es varchar por ello debes convertir los new a varchar

Código SQL [-]
    cSql = 'update tbsaldoscuentas ' ||
           ' set debetotal=debetotal+'||cast(new.debe as varchar(15)) || ', ' ||
           'habertotal=habertotal+'||cast(new.haber as varchar(15)) || ', ' ||
           :cCampoDebe  || '=' || :cCampoDebe  || '+' || 
           cast(new.debe as varchar(15)) || ', ' ||
           :cCampoHaber || '=' || :cCampoHaber || '+'||
           cast(new.haber as varchar(15))||
           ' where codigoempresa=codigoempresa ' ||
           ' and ejercicio=ejercicio ' ||
           ' and codigocuenta=codigocuenta';



Pruba y ya me diras

La where no la entiendo pero eso ya es otro problema

Saludos

Panta
Responder Con Cita
  #9  
Antiguo 19-12-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is online now
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Sí, gracias, celades1, ya me he dado cuenta, parece que al execute statement hay que darle todo bien "mascadito".
No sé si será mejor crear un store procedure que reciba el mes y punto. Haré pruebas a ver qué es más eficiente.
Responder Con Cita
  #10  
Antiguo 19-12-2010
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: dic 2003
Ubicación: Zamudio
Posts: 1.408
Poder: 22
fjcg02 Va camino a la fama
Hola a todos,

el problema qyue estás planteando no es el mismo que me ocurrió en esta ocasión ??

http://www.clubdelphi.com/foros/show...cute+statement

Si no recuerdo mal, el problema es que el execute statement no puede resolver las variables new.campo y old.campo fuera del ámbito del store p. o del trigger.

No estoy del todo seguro de si estamos itentando hacer lo mismo... ( es que es domingo por la tarde , haceos cargo ).

Ya me direis, ...

Saludos y suerte
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
Responder Con Cita
  #11  
Antiguo 19-12-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is online now
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Pues parece que sí, que es similar, el caso es que execute statement necesita la cadena completa, no se le puede pasar un campo para que obtenga el valor del mismo. En fin, no es muy práctico pero parece que va bien así:

Código SQL [-]
CREATE OR ALTER trigger tbapuntes_ai1 for tbapuntes
active after insert position 1
AS
  declare variable iMes integer;
  declare variable cCampoDebe  varchar(8);
  declare variable cCampoHaber varchar(8);
  declare variable cSql        varchar(1024);
  declare variable cValorDebe  varchar(18);
  declare variable cValorHaber varchar(18);
begin
  /* actualizar tbSaldosCuentas */
  if (new.codigoborrador>0) then  /* es borrador */
  begin
    update tbSaldosCuentas
    set debetotal=debetotal+new.debe,
        habertotal=habertotal+new.haber
    where codigoempresa=codigoempresa
    and ejercicio=ejercicio
    and codigocuenta=codigocuenta;
  end
  else /* no es borrador, es definitivo */
  begin
    iMes = extract(month from new.fechaasiento);
    cCampoDebe  = 'debe'  || cast(iMes as varchar(2));
    cCampoHaber = 'haber' || cast(iMes as varchar(2));
    cValorDebe  = cast(new.debe  as varchar(18));
    cValorHaber = cast(new.haber as varchar(18));

    cSql = 'update tbsaldoscuentas '||
           'set debetotal=debetotal+'||cValorDebe||
           ',habertotal=habertotal+'||cValorHaber||','||
           cCampoDebe  || '=' || cCampoDebe  || '+'||cValorDebe||','||
           cCampoHaber || '=' || cCampoHaber || '+'||cValorHaber||
           ' where codigoempresa='||cast(new.codigoempresa as varchar(18))||
           ' and ejercicio='||cast(new.ejercicio as varchar(18))||
           ' and codigocuenta='||''''||new.codigocuenta||'''';
/* --- debug --> */
/* insert into tbdebug (texto) values (:csql);*/
/* <-- debug --- */
    execute statement cSql;
  end
end
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
(SQL) Porqué usar parámetros en lugar de concatenar... Neftali [Germán.Estévez] La Taberna 3 27-01-2010 17:12:16
Como bloquear registros sin usar campos persistentes uper MS SQL Server 2 11-07-2007 19:10:06
usar variables de otras units anubis Varios 7 16-04-2007 10:24:04
DBGrid con campos variables mayte mtz SQL 9 16-11-2005 00:12:58
usar querys en lugar de tablas maruenda Varios 4 19-02-2004 00:03:13


La franja horaria es GMT +2. Ahora son las 21:36:57.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi