Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Tantos TQuery como consultas deseo? (https://www.clubdelphi.com/foros/showthread.php?t=61032)

Pollo2004 22-10-2008 20:15:39

Tantos TQuery como consultas deseo?
 
Hola a todos nuevamente, sigo muy agradecido por toda la ayuda brindada por el foro, y deseo mucho algun dia poder colaborar de la misma manera q lo hacen ustedes.
Estoy queriendo aprender un poco de SQL y mi pregunta es esta. yo a una tabla le puedo hacer muchas consultas, pongamos un ejemplo
Tengo una tabla de productos, y quiero buscar uno, tambien quiero controlar q ningun producto tenga stock= 0 y alguna otra q ustedes se imaginen.

otro ejemplo:
O buscar un producto por nombre, o codigo, o lo q fuese, tengo q poner un TQuery para cada busqueda y activar cada query con una accion de un boton o de otro componente.

Como seria la cosa?

Sigo usando paradox 7!
Gracias!

enecumene 22-10-2008 20:47:57

Hola, no amigo no es necesario un TQuery por cada búsqueda, con uno basta ejemplo:

Código Delphi [-]
if ComboBox1.Text = 'Codigo' then
  begin
     Query1.Close;
     Query1.SQL.Clear;
     Query1.SQL.Text := 'select * from tabla where codigo = '12345'';
     Query1.Open;
  end;
if ComboBox1.Text = 'Nombre' then
  begin
     Query1.Close;
     Query1.SQL.Clear;
     Query1.SQL.Text := 'select * from tabla where Nombre = 'Pedro'';
     Query1.Open;
  end;
if ComboBox1.Text = 'Producto' then
  begin
     Query1.Close;
     Query1.SQL.Clear;
     Query1.SQL.Text := 'select * from tabla where producto = 'Jabon'';
     Query1.Open;
  end;

en este ejemplo estoy usando un sólo Query.

Saludos.

roman 22-10-2008 20:54:51

Yo creo que es cuestión de organización. Si vas a usar un solo query para todas las consultas, posiblemente signifique o implique que vas a tener tus consultas desperdigadas por todo el código. Puede ser preferible tener las partes limpiamente separadas.

// Saludos

ContraVeneno 22-10-2008 20:56:33

Código Delphi [-]
with UnQuery do begin
 If active then close;
 SQL.Clear;
 SQL.Add('Select LosCampos ');
 SQL.Add('From UnTabla');
 Case ComboBox1.ItemIndex Of Begin
  0:   SQL.Add('Where Codigo = :Valor ');
  1:   SQL.Add('Where Nombre = :Valor ');
  2:   SQL.Add('Where Producto = :Valor ');
 end; //Case
 ParamByname('Valor').AsString := UnEdit.Text;
 Open;
end;  //with

coso 22-10-2008 21:26:55

Código Delphi [-]
q.Active := false;
q.SQL.Text := 'select * from tabla where ' + ComboBox.Text + ' = ' + QuotedStr(edit.text);
q.Active := true;
:D

AzidRain 22-10-2008 22:10:42

Puedes hacer un solo query para consultar por uno o varios campos así:

Código Delphi [-]
q.SQL.Add('select * from productos where (:clave is null or clave=:clave) AND (:nombre is null or nombre like :nombre) OR (:stock is null or stock>=:stock) ');

Solo tienes que llenar los parámetros según requieras, si no llenas ninguno te va a traer todos los registros. Esta es una forma muy sencilla de hacer combinaciones de condiciones y utilizas un solo query. De esta manera podrias traer por ejemplo: todos los productos que contengan "PRO" en su nombre y que tengan stock de mas de 10.
Para ello llenamos los parametros así:

Código Delphi [-]
 q.parambyName('nombre').AsString := '%PRO%';
q.ParamByName('stock').AsInteger  := 10;

ContraVeneno 22-10-2008 22:20:11

tómala, jejeje :D

rgstuamigo 22-10-2008 23:55:29

Ja,jaa,jaa,ja,ja,jaa:D:D, me sorprendieron:eek:.
Esta muy bueno, es lo que necesitaba tambien......;).

Pollo2004 23-10-2008 01:36:06

Gracias!!
 
Ahora manos a la obra y analizar y probar las soluciones q brindaron para ver cual es la q mas se adecua a mi situacion.
Cualquier sugerencia por favor, estaria bueno q la sigan posteando!
Gracias, salu2!!

coso 23-10-2008 12:04:32

te explico como trabajo yo : tengo ciertas querys generales que son las ligadas a las dbgrids. En ellas aplico los filtros necesarios etc, con nombres bien distinguibles (dmsrc.queryClientes,etc...). Para todas las otras operaciones (pasar datos de una a otra, encontrar un identificador concreto, cambiar campos relacionados etc...) entonces creo otra query correspondiente en la misma funcion en que se hace la operacion. Asi siempre tengo las querys 'visibles' mas o menos controladas. Es una manera personal, claro. Cada uno tiene la suya.

roman 23-10-2008 16:13:42

Concuerdo con lo que comenta coso y a eso me refería. Intentar reutilizar un sólo query para todas las consultas, tarde o temprano lleva a confusión.

Otra cosa. Acabo de probar la propuesta de AzidRain, y si bien me funciona con MySQL usando las componentes MyDAC, no así con Paradox usando el BDE. La consulta marca el error de "Type mismatch in expression" tanto si le paso valor al parámetro como si no.

// Saludos

marcoszorrilla 23-10-2008 17:05:56

Yo utilizo una opción mixta, para los casos particulares utilizo un Tquery para cada consulta incluso con campos persistentes. Pero para cosas generales como conteos, sumas, búsquedas...

Utilizo un Tquery sin campos ni contenido alguno y construyo por código el SQL que en cada momento necesito.


Un Saludo.

BlueSteel 23-10-2008 17:28:28

Yo soy partidario de crear consultas específicas y otras generales...

por ejemplo, mis diseños tiene en un Form la opción de mostrar un registro, agregar, eliminar y actualizar....

para esos tipos de Formularios siempre utilizo 3 consultas...

Como trabajo con ADO, las pondré así

1.- AQ_Select -> con la cual realizaré una selección de todos o parte de los registros
2.- AQ_Edit -> con la cual realizaré una inserción y/o eliminación
3.- AQ_Actualiza -> con la cual realizaré una actualización de un registro


Ahora, si necesito algo más específico, pongo tantas consultas como sea necesario y reutilizandolas al máximo....(tambien me debo acordar de lo que uso...)

bueno, si me baso en lo que dije, en un sistema donde tengo Clientes, Productos, Proveedores, Vendedores, Centros de Costos, y otros similares.... si bien es información diferente, con las 3 consultas anteriores cubro todas las consultas para cada uno de los Formularios...


Bueno, al menos así lo hago yo..

Salu2:p:D

elcolo83 23-10-2008 19:36:48

Hola a todos... Yo en mi caso ahora estoy provando una nueva forma de organizarme... vamos a ver como ve con esto...
Uso los componentes IBX y Firebird; lo que hago basicamente es crear un conjunto de componentes (TIBTransaction y TDBDataSet) por cada tabla automaticamente con la funcion CrearCompDB, el cual el mismo me genera el codigo SQL básico para editar, insertar, borrar y actualizar registros (ya que es muy tedioso hacerlo cuando tenes muchas tablas :p) cada conjunto de componentes es usado por lo modulos que editan sus datos.
Ademas tengo un modulo para busqueda simple el cual arma la consula dependiendo de la tabla que se vaya a consultar y muestra los campos en un grid, el cual abre el modulo correspondiente a la tabla que se esta consultando cuando se hace doble click en un registro del resultado...

En fin... no soy muy amigo de lo estatico y prefiero que el programa vaya armando y manipulando las consultas y componentes que se conectan segun la demanda del usuario.... Claro que hay que tener cuidado con el codigo para no consumir mas recursos de los necesarios.

La funcion que uso para crear los componentes y el codigo SQL basico

Código Delphi [-]
Procedure CrearCompDB(S:String; DB_: TIBDataBase);
var
  TR: TIBTransaction;
  DS: TIBDataSet;
  I: Integer;
begin
  //S es el nombre de la tabla a la cual se quiere conectar//
  S:= UpperCase(S); 


  TR:= TIBTransaction.Create(Application);
  TR.DefaultDatabase:= DB_;
  TR.Name:= 'TR'+S;

  DS:= TIBDataSet.Create(Application);
  DS.Database:= DB_;
  DS.Transaction:= TR;

  DB.GetFieldNames(S, L.Lines);

  DS.SelectSQL.Clear;
  DS.SelectSQL.Add('Select * from '+S);

  DS.InsertSQL.Clear;
  DS.InsertSQL.Add('INSERT INTO '+S+' (');
  for I := 0 to L.Lines.Count - 1 do
    begin
      if i<(L.Lines.Count-1) then
        DS.InsertSQL.Add(L.Lines[i]+',')
      else DS.InsertSQL.Add(L.Lines[i]+')');
    end;
  DS.InsertSQL.Add('VALUES (');
  for I := 0 to L.Lines.Count - 1 do
    begin
      if i<(L.Lines.Count-1) then
        DS.InsertSQL.Add(':'+L.Lines[i]+',')
      else DS.InsertSQL.Add(':'+L.Lines[i]+')');
    end;

  DS.ModifySQL.Clear;
  DS.ModifySQL.Add('UPDATE '+S+' SET');
  for I := 0 to L.Lines.Count - 1 do
   if L.Lines[i]<>'ID' then
    begin
      if i<(L.Lines.Count-1) then
        DS.ModifySQL.Add(L.Lines[i]+' = :'+L.Lines[i]+',')
      else DS.ModifySQL.Add(L.Lines[i]+' = :'+L.Lines[i]);
    end;
  DS.ModifySQL.Add('where ID= :OLD_ID');

  DS.DeleteSQL.Clear;
  DS.DeleteSQL.Add('DELETE FROM '+S+' WHERE ID = :OLD_ID');

  DS.RefreshSQL.Add('SELECT * FROM '+S+' WHERE ID = :ID');
  try
    DS.Active:= True;
  except
    on e:exception do
       ShowMessage(e.Message);
  end;
  DS.Name:= 'DS'+S;
  DS.AfterPost:= Commit;
  DS.OnPostError:= IBDataSet1.OnPostError;

  DSw.DataSet:= TDataSet(Application.FindComponent('DS'+S));
  DS.Active:= True;
end;

Saludos a todos

AzidRain 23-10-2008 19:53:33

Roman en el caso del BDE, me parece que hay que construir y definir los parámetros previamante. Tanto MyDAC como Zeos hacen la conversión de tipos al vuelo y no requieren que se los definas previamente. Checalo.

roman 23-10-2008 20:03:45

Creo que no Azid. Si quito la parte de

Código SQL [-]
:param is null

funciona bien sin necesidad de definir los parámetros. El tipo de datos se determina cuando usas ParamByName(...).AsXXX

Si asigno previamente el tipo de datos, sigue marcando el error.

// Saludos

roman 23-10-2008 20:33:50

elcolo83:

Tu idea es muy buena, pero quizá estás reinventando la rueda. Me explico:

No sé cómo funcionen los componentes IB, pero en otros similares, si pones una sentencia como esta:

Código SQL [-]
select * from tabla where id = :id

en la propiedad SQL, puedes hacer inserciones, actualizaciones y supresiones sin necesidad de especificar nada más. Incluso, por ejemplo, si modificas un registro, el SQL que se genera incluye sólo los campos modificados, mientras que como lo haces, siempre se incluyen todos.

Más aún. Si sigues el truco de AzidRain y pones la sentencia

Código SQL [-]
select * from tabla where id = :id or :id is null

entonces también te sirve para hacer selecciones.

Las propiedades InsertSql, UpdateSql y DeleteSql, creo que están más para casos en que se involucren varias tablas y la sentencia SQL adecuada no pueda deducirse en automático.

// Saludos

elcolo83 23-10-2008 22:10:53

Roman


Sinceramente nunca habia provado la sentencia con los IBX, mañana lo provare... si anda, seria genial ya que eliminaria la parte del codigo que me genera el codigo sql solo dejaria las lineas que crean los componentes para que mi sistema funcione...
Muy buena data... gracias, despues te cuento como me fue :)


La franja horaria es GMT +2. Ahora son las 18:52:48.

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