Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   problemas con consulta en un sp (https://www.clubdelphi.com/foros/showthread.php?t=49274)

Milperrimo 17-10-2007 17:49:14

problemas con consulta en un sp
 
Saludos, tengo un problemon aki en esta consulta porke necesito ke me regrese un solo registro con las sumas de todo lo ke kiero traer, pero me devuelve un registro por cada id, este es el sp
Código SQL [-]
SET TERM ^ ;
CREATE PROCEDURE TRAE3 (
 FECHAINI DATE,
 FECHAFIN DATE)
RETURNS (
 GS       FLOAT,
 MEC      INTEGER,
 SER      INTEGER,
 TC       INTEGER)
AS 
BEGIN FOR SELECT 
(SELECT SUM(GS) FROM HONDATA WHERE IDHONDATA = H.IDHONDATA) AS GS,
(SELECT COUNT(R.IDRETSER) FROM RETMR R WHERE R.IDHONDATA = H.IDHONDATA AND  R.IDRETSER = 1) AS MEC,
(SELECT COUNT(R.IDRETSER) FROM RETMR R WHERE R.IDHONDATA = H.IDHONDATA AND  R.IDRETSER = 2) AS SER,
(SELECT COUNT(R.IDRETSER) FROM RETMR R WHERE R.IDHONDATA = H.IDHONDATA AND R.IDRETSER = 3) AS TC
FROM ENCAOR E, HONDATA H
WHERE E.TIPO <> 'C' AND E.FECH BETWEEN :FECHAINI AND :FECHAFIN AND E.ORDE = H.ORDE AND EXTRACT(MONTH FROM (H.FECHORDE)) = EXTRACT(MONTH FROM(:FECHAFIN))
INTO :GS, :MEC, :SER, :TC
DO SUSPEND;
END^
SET TERM ; ^


el gs es un importe por lo que debe de traer la suma, los otros son tipos de algo, por lo que debe de traer el count de ellos.
en este caso en la tabla principal ke es hondata tengo 4 registros, de los cuales 2 cumplen con el requisito ke necesito ke es mandar la fecha, mando unas fechas de rango de marzo y de los 4 registros, 2 cumplen, por lo tanto me deve de traer el sp un registro con la suma de estos 2 pero me trae 2 registros, uno por cada uno, Como le hago para ke solo me mande uno con las sumas de los 2???????????????????????????// en el sqlserver no tenia problema alguno para traer este tipo de consultas. En el primer registro de la tabla el gs vale 56 y en segundo tambien, por lo que el resultado del sp debe de dar un registro con gs = 112 y MEC = 2 (los otros 2 en cero), pero en lugar de esto me da 2 registros con gs =56 y MEC =1 cada uno

Rudi 17-10-2007 19:32:55

Hola, Prueba con esto para no tocar mucho tu código:

nota: voy a poner en negrita lo que añadí.

Código Delphi [-]
SET TERM ^ ;
CREATE PROCEDURE TRAE3 (
 FECHAINI DATE,
 FECHAFIN DATE)
RETURNS (
 GS       FLOAT,
 MEC      INTEGER,
 SER      INTEGER,
 TC       INTEGER)
AS 
Declare variable Aux_GS    FLOAT;
Declare variable Aux_MEC  INTEGER;
Declare variable Aux_SER   INTEGER;
Declare variable Aux_TC    INTEGER;
BEGIN 
Aux_GS = 0;
Aux_MEC = 0;
Aux_SER = 0;
Aux_TC = 0;
FOR SELECT 
(SELECT SUM(GS) FROM HONDATA WHERE IDHONDATA = H.IDHONDATA) AS GS,
(SELECT COUNT(R.IDRETSER) FROM RETMR R WHERE R.IDHONDATA = H.IDHONDATA AND  R.IDRETSER = 1) AS MEC,
(SELECT COUNT(R.IDRETSER) FROM RETMR R WHERE R.IDHONDATA = H.IDHONDATA AND  R.IDRETSER = 2) AS SER,
(SELECT COUNT(R.IDRETSER) FROM RETMR R WHERE R.IDHONDATA = H.IDHONDATA AND R.IDRETSER = 3) AS TC
FROM ENCAOR E, HONDATA H
WHERE E.TIPO <> 'C' AND E.FECH BETWEEN :FECHAINI AND :FECHAFIN AND E.ORDE = H.ORDE AND EXTRACT(MONTH FROM (H.FECHORDE)) = EXTRACT(MONTH FROM(:FECHAFIN))
INTO :Aux_GS, :Aux_MEC, :Aux_SER, :Aux_TC
DO 
Begin
  GS = :GS + :Aux_GS;
  MEC = :MEC + :Aux_MEC;
  SER = :SER + :Aux_SER;
  TC = :TC + :Aux_TC;
  SUSPEND;
end
END^
SET TERM ; ^

No le he probado, asi que eso te toca a ti que ya tienes la estructura de las tabla y los datos de pruebas creados.

espero sea lo que necesitas, sino te sirve pega un grito y buscamos como solucionarlo.

Milperrimo 18-10-2007 05:16:22

Gracias por responder, no funciono del todo bien, me devuelve todo en null, no hay alguna manera de poner en el into :gs algo asi como into sum(:gs), count(:tc) etc??? algo parecido pues porke asi no me deja jeje,

duilioisola 18-10-2007 09:54:16

Quizás solo faltó inicializar las variables

Código SQL [-]
SET TERM ^ ;
CREATE PROCEDURE TRAE3 (
 FECHAINI DATE,
 FECHAFIN DATE)
RETURNS (
 GS       FLOAT,
 MEC      INTEGER,
 SER      INTEGER,
 TC       INTEGER)
AS 
Declare variable Aux_GS    FLOAT;
Declare variable Aux_MEC  INTEGER;
Declare variable Aux_SER   INTEGER;
Declare variable Aux_TC    INTEGER;
BEGIN 
  GS = 0;
  MEC = 0;
  SER = 0;
  TC = 0;
Aux_GS = 0;
Aux_MEC = 0;
Aux_SER = 0;
Aux_TC = 0;
FOR SELECT 
(SELECT SUM(GS) FROM HONDATA WHERE IDHONDATA = H.IDHONDATA) AS GS,
(SELECT COUNT(R.IDRETSER) FROM RETMR R WHERE R.IDHONDATA = H.IDHONDATA AND  R.IDRETSER = 1) AS MEC,
(SELECT COUNT(R.IDRETSER) FROM RETMR R WHERE R.IDHONDATA = H.IDHONDATA AND  R.IDRETSER = 2) AS SER,
(SELECT COUNT(R.IDRETSER) FROM RETMR R WHERE R.IDHONDATA = H.IDHONDATA AND R.IDRETSER = 3) AS TC
FROM ENCAOR E, HONDATA H
WHERE E.TIPO <> 'C' AND E.FECH BETWEEN :FECHAINI AND :FECHAFIN AND E.ORDE = H.ORDE AND EXTRACT(MONTH FROM (H.FECHORDE)) = EXTRACT(MONTH FROM(:FECHAFIN))
INTO :Aux_GS, :Aux_MEC, :Aux_SER, :Aux_TC
DO 
Begin
  GS = :GS + :Aux_GS;
  MEC = :MEC + :Aux_MEC;
  SER = :SER + :Aux_SER;
  TC = :TC + :Aux_TC;
  SUSPEND;
end
END^
SET TERM ; ^

Lepe 18-10-2007 10:32:20

Estuve mirando este hilo ayer pero no sabía por donde cogerlo.

El problema que veo es que haces un For select, y eso es un for para cada registro de la tabla, después, en su select vuelves a realizar otro select que suma:
Código SQL [-]
SELECT SUM(GS) FROM HONDATA WHERE IDHONDATA = H.IDHONDATA) AS GS

No sé, pero quizás fuese mejor realizar 3 selects distintos obteniendo las sumas:
Código SQL [-]
CREATE PROCEDURE TRAE3 (
 FECHAINI DATE,
 FECHAFIN DATE)
RETURNS (
 GS       FLOAT,
 MEC      INTEGER,
 SER      INTEGER,
 TC       INTEGER)
AS 
BEGIN 

SELECT SUM(GS) FROM HONDATA WHERE IDHONDATA = H.IDHONDATA) as GS
FROM ENCAOR E, HONDATA H
WHERE E.TIPO <> 'C' AND E.FECH BETWEEN :FECHAINI AND :FECHAFIN 
AND E.ORDE = H.ORDE AND EXTRACT(MONTH FROM (H.FECHORDE)) = EXTRACT(MONTH FROM(:FECHAFIN)) 

  and GS is not null
INTO :GS

...
-----------la otra sqls aqui -------

SELECT COUNT(R.IDRETSER) FROM RETMR R AS TC
FROM ENCAOR E, HONDATA H
WHERE R.IDHONDATA = H.IDHONDATA AND R.IDRETSER = 3)  
and E.TIPO <> 'C' AND E.FECH BETWEEN :FECHAINI AND :FECHAFIN 
AND E.ORDE = H.ORDE AND EXTRACT(MONTH FROM (H.FECHORDE)) = EXTRACT(MONTH FROM(:FECHAFIN))
into :TC

--- y después de tener todos los datos, devolvemos un único registro -----
 SUSPEND;
END^
SET TERM ; ^

Saludos

Milperrimo 18-10-2007 19:52:41

Saludos, estoy intentando hacer eso de tener un select por cada cosa, pero aun soy novato y tengo problemas con la sintaxis de sql en firebird, ya corregi los selects porke aqui en el copypaste que hiciste aparecen con 2 from y eso, ya corregi para que quedara cada select con su INTO :XXX, pero me marca un error justo arriba del segundo select, no se si va algo entre un select y otro, le intente con un ; pero no, no se que instruccion valla o ke, y otra cosa a que te refieres con:

--- y después de tener todos los datos, devolvemos un único registro -----

tengo ke poner alguna instruccion para esto??

Gracias por su ayuda!!!

Lepe 18-10-2007 21:10:45

Con tu permiso, empiezo citando desde el fin de tu mensaje:
Cita:

Empezado por Milperrimo (Mensaje 239485)
Gracias por su ayuda!!!

Hombreeeee, que en la vida cotidiana todos me hablan "de usted" porque estoy medio calvo.... vale, le doy un pase, pero que aquí también me hablen "de usted", no eso no :p:D:D.


Cita:

Empezado por Milperrimo (Mensaje 239485)
Saludos, estoy intentando hacer eso de tener un select por cada cosa, pero aun soy novato y tengo problemas con la sintaxis de sql en firebird, ya corregi los selects porke aqui en el copypaste que hiciste aparecen con 2 from y eso

Pues sí, se ve que me hice un lío, lo importante es que has entendido lo que quise decir ;).
Cita:

Empezado por Milperrimo (Mensaje 239485)
[...]para que quedara cada select con su INTO :XXX, pero me marca un error justo arriba del segundo select, no se si va algo entre un select y otro, le intente con un ; pero no, no se que instruccion valla o ke

No va nada, debería ir un punto y coma, algo así:
Código SQL [-]
select  bla bla 
from  blabla
where blabla
into :GS;

select  bla bla 
from  blabla
where blabla
into :GS;
Como ves las instrucciones se separan por ";", aunque una sentencia puede ocupar varias líneas de texto.
Revisa también los paréntesis abiertos y cerrados, que yo estaba hambriento y me he comido varios. Si no es eso, pon el SP final a ver que vemos entre todos.

Cita:

Empezado por Milperrimo (Mensaje 239485)
y otra cosa a que te refieres con:

--- y después de tener todos los datos, devolvemos un único registro -----

tengo ke poner alguna instruccion para esto??

No, lo puse como un pensamiento en voz alta, se refiere a que la siguiente línea (el "SUSPEND") lo que hace es eso, devolver un único registro.

Saludos

Milperrimo 19-10-2007 06:10:11

AL FINNNNNNNNNNNNNNNN!!!!!!!!!!!!!!!!!!!! ya funciono a la perfeccion asi haciendo un select por cada cosa y poniendo los ';' que faltaban, ya me saca un solo registro como debe ser, Muchisimas Gracias a todosss


La franja horaria es GMT +2. Ahora son las 19:05:44.

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