Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 12-11-2014
Delphitest Delphitest is offline
Miembro
 
Registrado: sep 2006
Ubicación: Salamanca-España
Posts: 249
Poder: 18
Delphitest Va por buen camino
Sentencia SQL con varios campos

Buenas Tardes,

pese a que hay mucha información en el foro relacionada con lo que busco, no soy capaz de ponerlo en practica y hacer que funcione.

He creado un Form para buscar en una Query un determinado cliente, para ello lo que pretendo es a través de varios edit y del evento onchange ir filtrando un DBGrid de tal manera que a medida que vaya escribiendo por ejemplo el nombre, los registros de la query se vayan adaptando a la búsqueda.

Pongo un pantallazo del Form y el codigo que estoy probando:

Código Delphi [-]
procedure TFBuscaCliente.Edit1Change(Sender: TObject);

var filtro1 :String;
var filtro2 :String;
var filtro3 :String;
var filtro4 :String;
var filtro5 :String;

begin
    If (Edit1.text <> '') then
    filtro1 := 'nombre like ' + QuotedStr('%' + Edit1.Text + '%');
    If (Edit2.text <> '') then
    filtro2 := 'Apellidos like ' + QuotedStr('%' + Edit2.Text + '%');
    If (Edit3.text <> '') then
    filtro3 := 'DNI like ' + QuotedStr('%' + Edit3.Text + '%');
    If (Edit4.text <> '') then
    filtro4 := 'Provincia like ' + QuotedStr('%' + Edit4.Text + '%');
    If (Edit5.text <> '') then
    filtro5 := 'Telefono_Fijo like ' + QuotedStr('%' + Edit5.Text + '%');
    IF (Edit1.Text = '') and (Edit2.Text = '') and (Edit3.Text = '') and (Edit4.Text = '') and (Edit5.Text = '') then
    begin
    TBuscarCliente.close;
    TBUscarCLiente.SQL.text :=  'Select * from clientes order by nombre';
    TBuscarCliente.open;
    end
    else
    begin
    TBuscarCLiente.Close;
    TBuscarCliente.SQL.Clear;
    TBUscarCLiente.SQL.text := 'Select * from clientes where ' + filtro1;
    TBuscarCliente.Open;
    end;
end;

http://www.clubdelphi.com/foros/atta...1&d=1415810826

Con lo que tengo hecho funciona perfectamente pero solo para el campo nombre (edit1) y si lo cambio para el apellido tambien funciona.

Lo que busco es, si se puede, que tenga en cuenta todos los edit a la hora de hacer el filtro. Asi si pongo "juan" en el nombre y "gon" en apellidos la busqueda sería más precisa.

Antes de preguntar he hecho combinaciones de variables e intentando concatenar con "and" la condición de la sql pero no doy con ello.

Si me pudierais orientar sería de agradecer.

Un saludo
Imágenes Adjuntas
Tipo de Archivo: jpg BuscarCliente.jpg (35,1 KB, 4 visitas)
__________________
Mi proyecto paso a paso (Parte I)
Responder Con Cita
  #2  
Antiguo 12-11-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Delphitest.

Si no entendí mal lo que consultas, podrías hacer algo parecido a este ejemplo:
Código Delphi [-]
begin
  with tu_Query do
  begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT APELLIDO, NOMBRE, DNI FROM CLIENTES');
    SQL.Add('WHERE APELLIDO LIKE :PAPE AND NOMBRE LIKE :PNOM AND DNI LIKE :PDNI');
    ParamByName('PAPE').AsString:= '%'+Edit1.Text+'%';
    ParamByName('PNOM').AsString:= '%'+Edit2.Text+'%';
    ParamByName('PDNI').AsString:= '%'+Edit3.Text+'%';
    Open;
  end;
end;
Toma en cuenta que la sintáxis puede variar un poco de acuerdo a los componentes que estes usando.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 12-11-2014
Delphitest Delphitest is offline
Miembro
 
Registrado: sep 2006
Ubicación: Salamanca-España
Posts: 249
Poder: 18
Delphitest Va por buen camino
Muchas Gracias por tu ayuda.

He intentado probar pero efectivamente algo falla en la sintaxis, uso ADO

He puesto esto:

Código Delphi [-]
    TBuscarCLiente.Close;
    TBuscarCliente.SQL.Clear;
    TBuscarCliente.SQL.Add('SELECT NOMBRE, APELLIDOS, DNI FROM CLIENTES');
    TBuscarCliente.SQL.Add('WHERE NOMBRE LIKE :PNON AND APELLIDOS LIKE :PAPE AND DNI LIKE :PDNI');
    TBuscarCliente.ParamByName('PNOM').AsString:= '%'+Edit1.Text+'%';
    TBuscarCliente.ParamByName('PAPE').AsString:= '%'+Edit2.Text+'%';
    TBuscarCliente.ParamByName('PDNI').AsString:= '%'+Edit3.Text+'%';
    TBuscarCliente.Open;

Pero me da error en las lineas donde uso ParamByName (Lo subraya en rojo)
__________________
Mi proyecto paso a paso (Parte I)
Responder Con Cita
  #4  
Antiguo 12-11-2014
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Prueba con

Código Delphi [-]
TBuscarCliente.Parameters.ParamByName('PNOM').Value := '%'+Edit1.Text+'%';

Es posible que antes tengas que poner:

Código Delphi [-]
TBuscarCliente.Parameters.ParamByName('PNOM').DataType := ftString;

// Saludos
Responder Con Cita
  #5  
Antiguo 12-11-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Delphitest.

Para los componentes ADO la sintaxis sería:
Código Delphi [-]
  with ADOQuery do
  begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT APELLIDO, NOMBRE, DNI FROM CLIENTES');
    SQL.Add('WHERE APELLIDO LIKE :PAPE AND NOMBRE LIKE :PNOM AND DNI LIKE :PDNI');
    Parameters.ParamByName('PAPE').Value:= '%'+Edit1.Text+'%';
    Parameters.ParamByName('PNOM').Value:= '%'+Edit2.Text+'%';
    Parameters.ParamByName('PDNI').Value:= '%'+Edit3.Text+'%';
    Open;
  end;
end;

Saludos

Edito: No había visto el mensaje de roman, pero comparto lo que te sugirió.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #6  
Antiguo 12-11-2014
Delphitest Delphitest is offline
Miembro
 
Registrado: sep 2006
Ubicación: Salamanca-España
Posts: 249
Poder: 18
Delphitest Va por buen camino
Mil gracias , así da gusto

Funciona a la perfección.

Muchísimas gracias por vuestra ayuda.
__________________
Mi proyecto paso a paso (Parte I)
Responder Con Cita
  #7  
Antiguo 12-11-2014
Delphitest Delphitest is offline
Miembro
 
Registrado: sep 2006
Ubicación: Salamanca-España
Posts: 249
Poder: 18
Delphitest Va por buen camino
Un detallín...

veo que cuando los registros tienen contenido en los 3 campos (nombre, apellidos y dni) no hay ningún problema con la búsqueda, pero si hay registros que tengan uno de esos campos vacíos no se incluyen en la búsqueda.

No se si lo he explicado bien, pero por ejemplo si existe un registro que tenga un nombre y los apellidos pero no tenga dni no hay forma de que aparezca al buscarlo sea por el campo que sea.

¿eso tendría solución o no me queda otra que dejarlo así?
__________________
Mi proyecto paso a paso (Parte I)
Responder Con Cita
  #8  
Antiguo 12-11-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Delphitest.

Una posibilidad sería considerar los campos con valor NULL:
Código Delphi [-]
begin
  with ADOQuery1 do
  begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT APELLIDO, NOMBRE, DNI FROM CLIENTES');
    SQL.Add('WHERE (APELLIDO LIKE :PAPE OR APELLIDO IS NULL) AND');
    SQL.Add('(NOMBRE LIKE :PNOM OR NOMBRE IS NULL) AND');
    SQL.Add('(DNI LIKE :PDNI OR DNI IS NULL)');
    Parameters.ParamByName('PAPE').Value:= '%'+Edit1.Text+'%';
    Parameters.ParamByName('PNOM').Value:= '%'+Edit2.Text+'%';
    Parameters.ParamByName('PDNI').Value:= '%'+Edit3.Text+'%';
    Open;
  end;
end;
Pero no se si te sirva de ese modo...

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #9  
Antiguo 13-11-2014
engranaje engranaje is offline
Miembro
 
Registrado: may 2011
Posts: 163
Poder: 13
engranaje Va por buen camino
Yo estas cosas suelo hacerlas asi:
Código Delphi [-]
var 
  bOtraCondicion:=boolean;
begin
  bOtraCondicion:=false; 
  with ADOQuery do  
  begin    
    Close;    
    SQL.Clear;    
    SQL.Add('SELECT APELLIDO, NOMBRE, DNI FROM CLIENTES');
 
    if ( (Edit1.Text <>'') and  (Edit2.Text <>'') (Edit3.Text <>'') ) then
    begin
      SQL.Add('WHERE');
   
      if  Edit1.Text <>'' then   
      begin
        SQL.Add('APELLIDO LIKE :PAPE ');
        bOtraCondicion:= true;        
        Parameters.ParamByName('PAPE').Value:= '%'+Edit1.Text+'%'; 
      end;
   
      if  Edit2.Text <>'' then   
      begin 
        if bOtraCondicion then
          SQL.Add('AND');     
        SQL.Add('NOMBRE LIKE :PNOM');     
        bOtraCondicion:= true;   
        Parameters.ParamByName('PNOM').Value:= '%'+Edit2.Text+'%';    
      end;
      
      if  Edit3.Text <>'' then   
      begin
        if bOtraCondicion then
          SQL.Add('AND');          
        SQL.Add('DNI LIKE :PDNI');   
        Parameters.ParamByName('PDNI').Value:= '%'+Edit3.Text+'%'; 
      end;
    end;
    Open;
  end;
end;
Responder Con Cita
  #10  
Antiguo 13-11-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por engranaje Ver Mensaje
Yo estas cosas suelo hacerlas asi:
Aunque funcione, es mejor usar la versión con parámetros mostrada por román y ecfisa. Evitas problemas de "inyección sql", además es la forma profesional de trabajar.
Deberías ir acostumbrándote a hacerlo con parámetros, el código queda más claro, simple y fácil de seguir. Seguro que si intentas cambiar, poco a poco, verás que te acostumbras a usar parámetros y ya no volverás a hacerlo de la otra manera.
Responder Con Cita
  #11  
Antiguo 13-11-2014
engranaje engranaje is offline
Miembro
 
Registrado: may 2011
Posts: 163
Poder: 13
engranaje Va por buen camino
Hombre técnicamente uso parámetros. Lo que pasa es que en vez de hacer consultas sobre campos que no necesito consultar lo que hago es añadir solo los parametros que necesito. Es cierto que es engorroso e igual debería pasarme a añadir todos los parámetros a la consulta y lanzarla sobre todos, teniendo en cuenta que cuando alguno va vacio quiero decir que puede tener cualquier valor incluido nulos... pero he pillado esta costumbre y me siento más comodo trabajando asi... será cuestión de probar tu recomendación.
Responder Con Cita
  #12  
Antiguo 13-11-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por engranaje Ver Mensaje
Hombre técnicamente uso parámetros. Lo que pasa es que en vez de hacer consultas sobre campos que no necesito consultar lo que hago es añadir solo los parametros que necesito. Es cierto que es engorroso e igual debería pasarme a añadir todos los parámetros a la consulta y lanzarla sobre todos, teniendo en cuenta que cuando alguno va vacio quiero decir que puede tener cualquier valor incluido nulos... pero he pillado esta costumbre y me siento más comodo trabajando asi... será cuestión de probar tu recomendación.
Sí, pero vas creando la sentencia poco a poco, eso es algo engorroso, sobre todo si luego tratas de hacer un cambio, tener que "cuadrar" todo de nuevo.
Sin embargo, de la otra forma (parámetros), cambias la sql y no tienes que hacer nada más.
Responder Con Cita
  #13  
Antiguo 13-11-2014
engranaje engranaje is offline
Miembro
 
Registrado: may 2011
Posts: 163
Poder: 13
engranaje Va por buen camino
Normalmente a la hora de generar una sentencia sql en la mayoria de los procesos creo la sentencia con parametros y la asigno a un tquery. Posteriormente cuando se necesita asigno los valores a los parametros y la abro. Pero esto solo lo hago cuando la consulta siempre va a tener valores para cada uno de los parametros.

Cuando me encuentro con una consulta que puede filtrarse por una serie de parametros en cualquier combinación de ellos desde 0 a todos utilizo una estructura en la que monto la consulta sin el where para el caso de que no se asigne valor a ningún parámetro, y si hay algún parámetro con valor los voi añadiendo uno a uno a la consulta.

Lo cierto es que por mas que le doy vueltas es la única forma que veo de tener una ventana de consulta con 6 edits por ejemplo para los datos de clientes y un boton de consulta de modo que si no relleno ningún edit me muestre todas los clientes, si relleno solo el nombre me muestre solo los que se llaman asi y si pongo el nombre y la calle me muestre todos los clientes que viven en esa calle y se llaman asi.

Sin compuner la consulta de este modo no se me ocurre como hacer que cuando un parámetro no tiene nigún
valor (o tiene '') la consulta se comporte como si en su lugar hubiera un " (campo is null or campo is not null),
por otra parte entiendo que por norma las consultas son mas rapidas cuanto menos campos haya en los filtros.

Si hay un modo de hacer lo que propuse en mi ejemplo solo con una texto de consulta sql fijo y nada mas que cambiando los parámetros me gustaría ver cual es para evitarme el "montaje" de la sentencia sql.
Responder Con Cita
  #14  
Antiguo 13-11-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Sí, a veces no queda más remedio que hacerlo como comentas
Responder Con Cita
  #15  
Antiguo 13-11-2014
Delphitest Delphitest is offline
Miembro
 
Registrado: sep 2006
Ubicación: Salamanca-España
Posts: 249
Poder: 18
Delphitest Va por buen camino
Pues agradecido de nuevo.

Probé con lo que comenta ecfisa pero aunque funciona bien no hace el filtro que necesito ya que muestra, ademas de lo que busco, los registros con campos vacíos.

Al final el código ha quedado como el que os pongo, es con el sistema de engranaje, no se si es lo correcto o no, no entiendo bien la parte que estais debatiendo, pero si que da el resultado que estoy buscando. He añadido hasta 5 edit para adaptarlo y puesto un OR en lugar de AND y ya está operativo.

Código Delphi [-]
procedure TFBuscaCliente.Edit1Change(Sender: TObject);

var bOtraCondicion :boolean;

begin
  bOtraCondicion:=false;
  with TBuscarCliente do
  begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT * FROM CLIENTES');

    if ( (Edit1.Text <>'') or  (Edit2.Text <>'') or (Edit3.Text <>'') or  (Edit4.Text <>'') or (Edit5.Text <>'') ) then
    begin
      SQL.Add('WHERE');

      if  Edit1.Text <>'' then
      begin
        SQL.Add('NOMBRE LIKE :PNOM ');
        bOtraCondicion:= true;
        Parameters.ParamByName('PNOM').Value:= '%'+Edit1.Text+'%';
      end;

      if  Edit2.Text <>'' then
      begin
        if bOtraCondicion then
        SQL.Add('AND');
        SQL.Add('APELLIDOS LIKE :PAPE');
        bOtraCondicion:= true;
        Parameters.ParamByName('PAPE').Value:= '%'+Edit2.Text+'%';
      end;

      if  Edit3.Text <>'' then
      begin
        if bOtraCondicion then
        SQL.Add('AND');
        SQL.Add('DNI LIKE :PDNI');
        Parameters.ParamByName('PDNI').Value:= '%'+Edit3.Text+'%';
      end;

      if  Edit4.Text <>'' then
      begin
        if bOtraCondicion then
        SQL.Add('AND');
        SQL.Add('PROVINCIA LIKE :PPROV');
        Parameters.ParamByName('PPROV').Value:= '%'+Edit4.Text+'%';
      end;

      if  Edit5.Text <>'' then
      begin
        if bOtraCondicion then
        SQL.Add('AND');
        SQL.Add('TELEFONO_FIJO LIKE :PTFNO');
        Parameters.ParamByName('PTFNO').Value:= '%'+Edit5.Text+'%';
      end;

    end;
    Open;
  end;
end;


Gracias de nuevo a todos, con todos los errores que me han surgido en este tiempo he aprendido ademas de lo buscaba otras cosillas, esto es un mundo y todos los días se aprende algo nuevo.

Un abrazo
__________________
Mi proyecto paso a paso (Parte I)
Responder Con Cita
Respuesta



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
ayuda con sentencia sql para campos blob en interbase xor Firebird e Interbase 3 16-10-2007 22:52:52
varios campos en un dblookupcombobox anubis Varios 6 26-06-2007 04:24:50
como funciona la sentencia locate para campos multiples lugabame Tablas planas 3 17-05-2007 07:52:34
Agregar Varios campos en la sentencia SELECT m.ruiz SQL 5 23-01-2007 17:42:09
Top con varios campos trex2000 MS SQL Server 1 04-10-2006 21:12:15


La franja horaria es GMT +2. Ahora son las 06:20: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
Copyright 1996-2007 Club Delphi