Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Consulta sql anidada (https://www.clubdelphi.com/foros/showthread.php?t=93983)

ralf8727 07-06-2019 02:25:57

Consulta sql anidada
 
Buen dia tengo el siguiente problema

una consulta sql que se realiza desde delphi con estos campos

m1= largo dos edits
m2=ancho dos edits
m3=espesor dos edits
m4=alto dos edits
m5=numerodebarrenos 1 edit

los datos los ingresa el usuario la consulta que tengo es la siguiente

Código Delphi [-]FILTROP.Close; FILTROP.SQL.Clear; FILTROP.SQL.Add('SELECT MARCA,CODIGO,FORMULA,NUMERO,DESCRI,CODIGOI FROM INVENTA WHERE '); if (Edit1.Text<>'') AND (Edit2.Text<>'') then BEGIN FILTROP.SQL.Add('M1 BETWEEN :M1 AND :M2 '); FILTROP.Parameters.ParamByName('M1').Value:=Edit1.Text; FILTROP.Parameters.ParamByName('M2').Value:=Edit2.Text; if (Edit3.Text<>'') OR (Edit4.Text<>'') OR (Edit5.Text<>'') OR (Edit6.Text<>'') OR (Edit7.Text<>'') OR (Edit8.Text<>'') OR (Edit9.Text<>'') OR (Edit10.Text<>'') OR (Edit11.Text<>'') OR (Edit12.Text<>'') OR (Edit13.Text<>'') THEN BEGIN FILTROP.SQL.Add(' ,'); END; END;


si el usuario ingresa informacion al edit 1 y al edit 2 el parametro se asigna a m1
pero si intenta filtrar por mas campos no logro que funcione la busqueda lo que quiero lograr es un filtro que sea por dimenciones he intentar filtrar lo mas posible la informacion.

gracias por su ayuda.

oscarac 07-06-2019 07:27:15

y que tal si en lugar de usar parametros lo solucionas armando una cadena

algo asi como:

Código Delphi [-]
cadena := '';

if Edit1.Text<>'' then Cadena := cadena + edit1.text
if Edit2.Text<>'' then Cadena := cadena + edit2.text
if Edit3.Text<>'' then Cadena := cadena + edit3.text
if Edit4.Text<>'' then Cadena := cadena + edit4.text
if Edit5.Text<>'' then Cadena := cadena + edit5.text
if Edit6.Text<>'' then Cadena := cadena + edit6.text
if Edit7.Text<>'' then Cadena := cadena + edit7.text
if Edit8.Text<>'' then Cadena := cadena + edit8.text


yo tengo una funcion que una cadena de caracteres la separa en comas, para que se pueda ejecutar el sql usando IN

Código Delphi [-]
Function _Digito(_String : string ; _Tipo :Integer) :String;
var _Dig :String; _i :Integer;
begin
  _Dig := '';
  if _tipo = 0 then
    begin
      For _i:= 1 to Length(_string) do
        _Dig := _Dig + Copy (_String, _i, 1) +  ',';
      Result := Copy (_Dig,1, Length(_DIG) -1);
    end
  Else
  begin
      For _i:= 1 to Length(_string) do
        _Dig := _Dig + QuotedStr(Copy (_String, _i, 1)) +  ',';
      Result := '(' + Copy (_Dig,1, Length(_DIG) -1) +')';

  end;
end;

si la ejecuto asi
_cad := _digito ('1234',1)

el resultado es ('1','2','3','4')


entonces en la consulta sql podria usar...

SELECT MARCA,CODIGO,FORMULA,NUMERO,DESCRI,CODIGOI FROM INVENTA WHERE M1 in _cad


yo lo hago mas o menos asi

Código Delphi [-]
_CadDB := _Digito('D1I+',1);
  _CadHB := _Digito('H2S-',1);
  While not qryPlanContable.Eof do
  Begin

    Strsql := 'select Left(M.cuenta, 2) As Cuenta, M.Libro, Lbr.Descripcion As DLibro, ';
    if rgMoneda.ItemIndex = 1 then
      Strsql := Strsql +  'SUM (Case when M.DH in ' + _CadDB + ' then M.u_IMP else 0.00 End) AS DEBE, ' +
                          'SUM (Case when M.DH in ' + _CadHB + ' then M.u_IMP else 0.00 End) AS HABER, ' +
                          'SUM (Case when M.DH in ' + _CadDB + ' then M.n_IMP else 0.00 End) AS DEBEMN, ' +
                          'SUM (Case when M.DH in ' + _CadHB + ' then M.n_IMP else 0.00 End) AS HABERMN, ' +
                          'SUM (Case when M.DH in ' + _CadDB + ' then M.u_IMP else 0.00 End) AS DEBEME, ' +
                          'SUM (Case when M.DH in ' + _CadHB + ' then M.u_IMP else 0.00 End) AS HABERME '
    Else
      Strsql := Strsql +  'SUM (Case when M.DH in ' + _CadDB + ' then M.n_IMP else 0.00 End) AS DEBE, ' +
                          'SUM (Case when M.DH in ' + _CadHB + ' then M.n_IMP else 0.00 End) AS HABER, ' +
                          'SUM (Case when M.DH in ' + _CadDB + ' then M.n_IMP else 0.00 End) AS DEBEMN, ' +
                          'SUM (Case when M.DH in ' + _CadHB + ' then M.n_IMP else 0.00 End) AS HABERMN, ' +
                          'SUM (Case when M.DH in ' + _CadDB + ' then M.u_IMP else 0.00 End) AS DEBEME, ' +
                          'SUM (Case when M.DH in ' + _CadHB + ' then M.u_IMP else 0.00 End) AS HABERME ';
    Strsql := Strsql +  'from (tblmovimientocontable M with (nolock) ' +
              ' Left Join TblLibro Lbr with (nolock) ON (Lbr.Empresa = M.Empresa and Lbr.KOD = M.Libro)) '  +
              ' where M.Empresa = ' + QuotedStr(dmGlobal.g_CodigoEmpresa) + ' and M.Periodo = ' + QuotedStr(dmGlobal.g_Periodo) +
              ' and Left (M.cuenta,2) = '+ QuotedStr(qryPlanContableCuenta.AsString) +
              ' Group by Left(M.CUENTA,2), M.Libro, Lbr.Descripcion  ' +
              'order by Left(M.CUENTA,2), M.Libro';



quiza eso pueda ayudarte

bucanero 07-06-2019 11:53:28

hola

yo para este tipo de consultas con filtros estáticos utilizo una estructura fija de SELECT (sin necesidad de cambiar o ajustar el SQL en runtime) como esta:

Código SQL [-]
SELECT MARCA,CODIGO,FORMULA,NUMERO,DESCRI,CODIGOI 
FROM INVENTA 
WHERE
  (:minLargo is null or :minLargo <= m1) and
  (:maxLargo is null or m1 <= :maxLargo ) and 
  (:minAncho is null or :minAncho <= m2) and
  (:maxAncho is null or m2 <= :maxAncho ) and 
  (:minAlto is null or :minAlto <= m4) and
  (:maxAlto is null or m4 <= :maxAlto ) 
  -- and  -- resto de opciones --


y los parámetros los cargo de la siguiente forma:


Código Delphi [-]
procedure TForm2.FILTROPBeforeOpen(DataSet: TDataSet);
  procedure SetParamsAsInt(AParam: TParam; AEdit: TEdit);
  var
    AValue:integer;
  begin
    if (AEdit.Text = '') or not TryStrToInt(AEdit.text, AValue) then
      AParam.Clear
    else
       AParam.AsInteger:=AValue;
  end;

begin
  with filtroP, Params do begin
    SetParamsAsCurr(ParamByName('minLargo'), Edit1);
    SetParamsAsCurr(ParamByName('maxLargo'), Edit2);
    SetParamsAsInt(ParamByName('minAncho'), Edit3);
    SetParamsAsInt(ParamByName('maxAncho'), Edit4);
    SetParamsAsInt(ParamByName('minAlto'), Edit5);
    SetParamsAsInt(ParamByName('maxAlto'), Edit6);
  end;
end;

De tal forma que si el usuario no rellena alguno de los campos de busqueda, ese campo se queda sin efecto

ralf8727 07-06-2019 17:55:42

oscarac,bucanero
 
Gracias por sus ideas las pondre en practica y les comento como funcionaron.

ralf8727 07-06-2019 18:50:38

Cita:

Empezado por bucanero (Mensaje 532321)
hola

yo para este tipo de consultas con filtros estáticos utilizo una estructura fija de SELECT (sin necesidad de cambiar o ajustar el SQL en runtime) como esta:

Código SQL [-]SELECT MARCA,CODIGO,FORMULA,NUMERO,DESCRI,CODIGOI FROM INVENTA WHERE (:minLargo is null or :minLargo <= m1) and (:maxLargo is null or m1 <= :maxLargo ) and (:minAncho is null or :minAncho <= m2) and (:maxAncho is null or m2 <= :maxAncho ) and (:minAlto is null or :minAlto <= m4) and (:maxAlto is null or m4 <= :maxAlto ) -- and -- resto de opciones --



y los parámetros los cargo de la siguiente forma:


Código Delphi [-]procedure TForm2.FILTROPBeforeOpen(DataSet: TDataSet); procedure SetParamsAsInt(AParam: TParam; AEdit: TEdit); var AValue:integer; begin if (AEdit.Text = '') or not TryStrToInt(AEdit.text, AValue) then AParam.Clear else AParam.AsInteger:=AValue; end; begin with filtroP, Params do begin SetParamsAsCurr(ParamByName('minLargo'), Edit1); SetParamsAsCurr(ParamByName('maxLargo'), Edit2); SetParamsAsInt(ParamByName('minAncho'), Edit3); SetParamsAsInt(ParamByName('maxAncho'), Edit4); SetParamsAsInt(ParamByName('minAlto'), Edit5); SetParamsAsInt(ParamByName('maxAlto'), Edit6); end; end;


De tal forma que si el usuario no rellena alguno de los campos de busqueda, ese campo se queda sin efecto


no logro hacer funcionar este ejemplo

al compilar dice este error

[DCC Error] Busquedaavanzada.pas(286): E2003 Undeclared identifier: 'param'
[DCC Error] Busquedaavanzada.pas(290): E2003 Undeclared identifier: 'ParamByName'

y ya le cambie todos lo que se me pudo ocurrir utilizo delphi 2010

bucanero 07-06-2019 19:27:44

¿de que clase es tu componente filtroP?, en mis pruebas lo hice con un TZQuery de las zeos, y para esta clase a los parámetros se accede mediante la propiedad params. Si por el contrario utilizas un TADOQuery entonces se accede mediante la propiedad Parameters, con otros componentes de base de datos es posible que la propiedad sea otra distinta.

En tu código, ya utilizabas la función ParamByName, así que en tu caso en particular supongo que debes de utilizar Parameters

Código Delphi [-]
FILTROP.Parameters.ParamByName('M1').Value:=Edit1.Text;

ralf8727 07-06-2019 21:08:40

Gracias por la aclaracion esta en lo correcto es un TADOQuery
 
Cita:

Empezado por bucanero (Mensaje 532325)
¿de que clase es tu componente filtroP?, en mis pruebas lo hice con un TZQuery de las zeos, y para esta clase a los parámetros se accede mediante la propiedad params. Si por el contrario utilizas un entonces se accede mediante la propiedad Parameters, con otros componentes de base de datos es posible que la propiedad sea otra distinta.

En tu código, ya utilizabas la función ParamByName, así que en tu caso en particular supongo que debes de utilizar Parameters

Código Delphi [-]FILTROP.Parameters.ParamByName('M1').Value:=Edit1.Text;

:D:D me falto ese detalle del TADOQuery gracias^\||/^\||/^\||/^\||/


La franja horaria es GMT +2. Ahora son las 17:09:56.

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