Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Consulta con el HAVING por parámetro (https://www.clubdelphi.com/foros/showthread.php?t=76140)

rubio 11-10-2011 16:12:33

Consulta con el HAVING por parámetro
 
Hola amigos del foro, de antemano gracias a todos aquellos que se interesen por este hilo y a los que me ayuden en la solución. Tengo una consulta que la ejecuto dentro de un procedimiento almacenado, estoy usando SQL 2000, pero quisiera pasar la condición del HAVING como parámetro al procedimiento.

Lo tengo así:

Código SQL [-]
CREATE PROCEDURE dbo.Factura1 AS

SELECT     dbo.OT.OT, SUM(dbo.OT.ImpCUC) AS ImpCUC, SUM(dbo.OT.ImpMN) AS ImpMN, dbo.OT.IdCentral, dbo.Entidades.Descripcion, dbo.Motores.Marca, 
                      dbo.Motores.Modelo, dbo.Horas.Horas, dbo.Centrales.Nombre, dbo.OTObservaciones.Observaciones, dbo.OT.Bateria, dbo.OT.Motor
FROM         dbo.OT LEFT OUTER JOIN
                      dbo.Entidades ON dbo.OT.IdEntidad = dbo.Entidades.IdEntidad LEFT OUTER JOIN
                      dbo.Motores ON dbo.OT.IdMotor = dbo.Motores.IdMotor LEFT OUTER JOIN
                      dbo.Horas ON dbo.OT.IdHoras = dbo.Horas.IdHoras LEFT OUTER JOIN
                      dbo.Centrales ON dbo.OT.IdCentral = dbo.Centrales.IdCentral LEFT OUTER JOIN
                      dbo.OTObservaciones ON dbo.OT.OT = dbo.OTObservaciones.OT
GROUP BY dbo.OT.OT, dbo.OT.IdCentral, dbo.Entidades.Descripcion, dbo.Motores.Marca, dbo.Motores.Modelo, dbo.Horas.Horas, dbo.Centrales.Nombre, 
                      dbo.OTObservaciones.Observaciones, dbo.OT.Bateria, dbo.OT.Motor
HAVING      (dbo.OT.OT = 252011)
GO


pero quisiera poder hacer esto:

Código SQL [-]
CREATE PROCEDURE dbo.Factura1

@SHaving CHAR(256)

AS

SELECT     dbo.OT.OT, SUM(dbo.OT.ImpCUC) AS ImpCUC, SUM(dbo.OT.ImpMN) AS ImpMN, dbo.OT.IdCentral, dbo.Entidades.Descripcion, dbo.Motores.Marca, 
                      dbo.Motores.Modelo, dbo.Horas.Horas, dbo.Centrales.Nombre, dbo.OTObservaciones.Observaciones, dbo.OT.Bateria, dbo.OT.Motor
FROM         dbo.OT LEFT OUTER JOIN
                      dbo.Entidades ON dbo.OT.IdEntidad = dbo.Entidades.IdEntidad LEFT OUTER JOIN
                      dbo.Motores ON dbo.OT.IdMotor = dbo.Motores.IdMotor LEFT OUTER JOIN
                      dbo.Horas ON dbo.OT.IdHoras = dbo.Horas.IdHoras LEFT OUTER JOIN
                      dbo.Centrales ON dbo.OT.IdCentral = dbo.Centrales.IdCentral LEFT OUTER JOIN
                      dbo.OTObservaciones ON dbo.OT.OT = dbo.OTObservaciones.OT
GROUP BY dbo.OT.OT, dbo.OT.IdCentral, dbo.Entidades.Descripcion, dbo.Motores.Marca, dbo.Motores.Modelo, dbo.Horas.Horas, dbo.Centrales.Nombre, 
                      dbo.OTObservaciones.Observaciones, dbo.OT.Bateria, dbo.OT.Motor
HAVING      (SHaving)
GO

pero al ejecutarlo me da error.

Agradezco toda la ayuda que me puedan dar para resolver el problema. Gracias a todos.

oscarac 11-10-2011 16:14:50

y que error es el que te sale?

rubio 11-10-2011 16:20:05

Error 170: Linea 17: sintaxis incorrecta cerca de ')'

oscarac 11-10-2011 16:28:50

y como estas mandando el parametro?

rubio 11-10-2011 16:58:22

Oscarac gracias por interesarte por mi problema, el error me lo dá cuando estoy creando el procedimiento almacenado, o sea, que aún no he ejecutado el procedimiento por primera vez.

orioncomputer 11-10-2011 19:18:56

Saludos, rubio.
No he probado tu consulta SQl, pero a simple vista creo que el error esta en:
1.- Asi me dices que te funciona?
Cita:

HAVING (dbo.OT.OT = 252011)
2.- Luego intentas hacer esto
Cita:

HAVING (SHaving)
y deberias hacerlo Asi:
Cita:

HAVING (dbo.OT.OT = SHaving)
ya que asumo que la consulta no es inteligente y pueda asumir que cosa quieres filtrar.

Sin mas......

Prueba y comenta :):)

oscarac 11-10-2011 19:20:48

no debeiria ser asi?

having (@shaving)

rubio 11-10-2011 19:33:07

Hola orioncomputer, gracias por interesarte, quizas no me he explicado bien, el problema es el siguiente:

SHaving puede venir de diferentes formas:
1.- (dbo.OT.OT = 252011)
2.- (dbo.OT.OT = 252011) OR (dbo.OT.OT = 255011) OR (dbo.OT.OT = 266057) ....

o sea, yo conformo la condición del HAVING en dependencia de la cantidad de OT que fueron seleccionadas por el usuario.

Entiendes por qué debo hacerlo así, si tienes una solución para el problema por favor decirmelo.

Gracias...

rubio 11-10-2011 19:35:53

Oscarac, lo probé y me el mismo error.

Gracias.

oscarac 11-10-2011 19:37:57

da un ejemplo de como lo estas mandando en este momento... que valor le estas dando al parametro

rubio 11-10-2011 20:15:23

Oscarac, te decia que el error me lo da construyendo el procedimiento almacenado en el Enterprise Manager de SQL, cuando le doy comprobar la sintaxis, me sale el error. en la respuesta que le ofrecí a orioncomputer le decía que el parámetro puede tomar diferentes valores ya que es construido de acuerdo a la cantidad de OT que seleccione el usuario, puede ser así:

1.- (dbo.OT.OT = 252011)
2.- (dbo.OT.OT = 252011) OR (dbo.OT.OT = 255011) OR (dbo.OT.OT = 266057) ....

no se si me entiendes.

Primero creo el parámetro:

Código Delphi [-] for I:=0 to (clbOT.Items.Count -1) do begin bSi:=True; if clbOT.Checked[i]=True then begin sOT:=MidStr(clbOT.Items[i],1,(Pos(' ',clbOT.Items[i])-1)); if bPrimera=True then begin sHav:='(((OT.OT)=' + sOT; bPrimera:=False; bSegunda:=True; end else if bSegunda=True then sHav:=sHav + ' OR (OT.OT)=' + sOT; end; end; if bSi=True then sHav:=sHav + '))'; end;


Para llamarlo sería así:

Crear un ADOCommand.

Código Delphi [-]
ADOCommand.CommandType:=cmdStoredProc;   ADOCommand.Connection:=La conexión del sistema;   ADOCommand.CommandText:=Nombre del Procedimiento;   ADOCommand.Parameters.Refresh;   ADOCommand.Parameters.ParamByName('@SHaving').Value:=sHav;

Entiendes lo que quiero hacer.

Gracias.

oscarac 11-10-2011 21:24:00

y estas seguro que la cedana resultante esta bien?
chequea que valor tiene la cadena

rubio 11-10-2011 21:44:22

Oscarac, amigo no me entiendes, yo no llego a terminar el procemiento almacenado, ya que cuando lo voy a probar la sintaxis me da el error y no meja salvarlo de esta forma:

Código SQL [-]
CREATE PROCEDURE dbo.Factura1  @SHaving CHAR(256)  AS  SELECT     dbo.OT.OT, SUM(dbo.OT.ImpCUC) AS ImpCUC, SUM(dbo.OT.ImpMN) AS ImpMN, dbo.OT.IdCentral, dbo.Entidades.Descripcion, dbo.Motores.Marca,                        dbo.Motores.Modelo, dbo.Horas.Horas, dbo.Centrales.Nombre, dbo.OTObservaciones.Observaciones, dbo.OT.Bateria, dbo.OT.Motor FROM         dbo.OT LEFT OUTER JOIN                       dbo.Entidades ON dbo.OT.IdEntidad = dbo.Entidades.IdEntidad LEFT OUTER JOIN                       dbo.Motores ON dbo.OT.IdMotor = dbo.Motores.IdMotor LEFT OUTER JOIN                       dbo.Horas ON dbo.OT.IdHoras = dbo.Horas.IdHoras LEFT OUTER JOIN                       dbo.Centrales ON dbo.OT.IdCentral = dbo.Centrales.IdCentral LEFT OUTER JOIN                       dbo.OTObservaciones ON dbo.OT.OT = dbo.OTObservaciones.OT GROUP BY dbo.OT.OT, dbo.OT.IdCentral, dbo.Entidades.Descripcion, dbo.Motores.Marca, dbo.Motores.Modelo, dbo.Horas.Horas, dbo.Centrales.Nombre,                        dbo.OTObservaciones.Observaciones, dbo.OT.Bateria, dbo.OT.Motor HAVING      (SHaving) GO

Que pasa, eso está programado para ser usado con base de datos en ACCESS y yo lo estoy pasando a SQL te pongo la sintaxis para que veas como está ahora,:

Código Delphi [-]
  MDIPrincipal.UsoSQL('SELECT OT.OT, Sum(OT.ImpCUC) AS ImpCUC,'
    + ' Sum(OT.ImpMN) AS ImpMN, OT.IdCentral, Entidades.Descripcion,'
    + ' Motores.Marca, Motores.Modelo, Horas.Horas, Centrales.Nombre,'
    + ' OTObservaciones.Observaciones, OT.Bateria, OT.Motor'
    + ' FROM ((((OT LEFT JOIN Entidades ON OT.IdEntidad = Entidades.IdEntidad)'
    + ' LEFT JOIN Motores ON OT.IdMotor = Motores.IdMotor)'
    + ' LEFT JOIN Horas ON OT.IdHoras = Horas.IdHoras)'
    + ' LEFT JOIN Centrales ON OT.IdCentral = Centrales.IdCentral)'
    + ' LEFT JOIN OTObservaciones ON OT.OT = OTObservaciones.OT'
    + ' GROUP BY OT.OT, OT.IdCentral, Entidades.Descripcion, Motores.Marca,'
    + ' Motores.Modelo, Horas.Horas, Centrales.Nombre,'
    + ' OTObservaciones.Observaciones, OT.Bateria, OT.Motor'
    + ' HAVING ' + sHav, frmFacturas.ADOQTMP);

UsoSQL es una función:

Código Delphi [-]
procedure TMDIPrincipal.UsoSQL(SQL: String; QR: TObject);
begin
  (QR As TADOQuery).Connection:= mdiprincipal.ACPrincipal;
  (QR As TADOQuery).Active:=False;
  (QR As TADOQuery).SQL.Clear;
  (QR As TADOQuery).SQL.Add(SQL);
  (QR As TADOQuery).Active:=True;
end;

Te repito donde me da el error es creando el procedimiento en el enterprise manager, yo me pregunto si no faltará
algo para concatenar la palabra HAVING con el parámetro que se le pasa al procedimiento?

Gracias.

oscarac 11-10-2011 21:51:51

yo creo que TU no entendiste lo que te pregunte...

quiero el valor de la cadena sHAV

rubio 11-10-2011 21:58:16

El valor de la cadena es el siguiente:

((dbo.OT.OT=292011) OR (dbo.OT.OT=302011) OR (dbo.OT.OT=322011))

abelg 12-10-2011 14:59:43

Hola si mal no entiendo es esto lo que estas buscando.

Código SQL [-]
CREATE PROCEDURE dbo.Factura1
@SHaving CHAR(256)
AS
begin
  declare @Select varchar(max)
  
  set @Select = '  
  SELECT     dbo.OT.OT, SUM(dbo.OT.ImpCUC) AS ImpCUC, SUM(dbo.OT.ImpMN) AS ImpMN, dbo.OT.IdCentral, dbo.Entidades.Descripcion, dbo.Motores.Marca, 
                      dbo.Motores.Modelo, dbo.Horas.Horas, dbo.Centrales.Nombre, dbo.OTObservaciones.Observaciones, dbo.OT.Bateria, dbo.OT.Motor
  FROM         dbo.OT LEFT OUTER JOIN
                      dbo.Entidades ON dbo.OT.IdEntidad = dbo.Entidades.IdEntidad LEFT OUTER JOIN
                      dbo.Motores ON dbo.OT.IdMotor = dbo.Motores.IdMotor LEFT OUTER JOIN
                      dbo.Horas ON dbo.OT.IdHoras = dbo.Horas.IdHoras LEFT OUTER JOIN
                      dbo.Centrales ON dbo.OT.IdCentral = dbo.Centrales.IdCentral LEFT OUTER JOIN
                      dbo.OTObservaciones ON dbo.OT.OT = dbo.OTObservaciones.OT
  GROUP BY dbo.OT.OT, dbo.OT.IdCentral, dbo.Entidades.Descripcion, dbo.Motores.Marca, dbo.Motores.Modelo, dbo.Horas.Horas, dbo.Centrales.Nombre, 
                      dbo.OTObservaciones.Observaciones, dbo.OT.Bateria, dbo.OT.Motor 
  '
  exec (@select + ' Having ' + @SHaving )
  
end
GO

en la variable @SHaving mandas lo que quieres pero que coincida con la query.
Saludos.

rubio 12-10-2011 21:50:29

Hola abelg, gracias por interesarte por el tema, es muy interesante la respuesta que me das, pero al pasarlo al enterprise manager me da error en esta linea:

declare @Select varchar(max)

el error que da es el siguiente:

Error 170: Linea 5: sintaxis incorrecta cerca de 'max'.
Debe declarar la variable '@Select'
no logro enteder el error, ya que la variable está siendo declarada en ese momento.

Saludos

oscarac 12-10-2011 21:56:39

no sera que el nombre de la variable es igual a una palabra reservada?
intenta definir la variable con otro nombre.. _Select por ejemplo

rubio 12-10-2011 22:12:24

Hola oscarac, ya me había saltado esa duda y la cambié, le puse @Select_12 y me dió el mismo error.

Saludos

oscarac 12-10-2011 22:30:31

en lugar de MAX coloca 255 (esperemos que la consulta no llegue a tantos caracteres)


La franja horaria es GMT +2. Ahora son las 19:38:16.

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