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)
-   -   TQuery con parámetro (https://www.clubdelphi.com/foros/showthread.php?t=83229)

bulc 23-05-2013 20:19:43

TQuery con parámetro
 
Un código de llamada TQuery que funciona, pero al adaptarlo a un parámetro deja el TDBGrid activo pero vacío. Aquí va:
Código Delphi [-]
Var
cIni : String ;
begin
InputBox('Introduzca lo que busca: ', 'Item:', cIni );
//Try to use Parameters but failes:
   IBQuery1.Close;       // 1
  IBTransaction1.Active:= False; //2
  ClientDataSet1.Active:=False; //3
  DataSource1.Enabled := False;  //4
  DBGrid1.Enabled:= False;   //5

IBQuery1.SQL.Clear;
IBQuery1.SQL.Add('SELECT * FROM WB WHERE ITEM STARTING WITH :cInicial  ');
IBQuery1.ParamByName('cInicial').Value:=cIni ;
IBQuery1.Open;
   DataSource1.Enabled := True; //4
   IBTransaction1.Active:= True;  //2
      ClientDataSet1.Active:=True;
      DBGrid1.Enabled:= True;
   //DBGrid1.Refresh; Not needed
end;

Casimiro Noteví 23-05-2013 20:50:48

Amigo bulc, ¿recuerdas el libro que te indiqué?, ¿y los tutoriales?, y los ejemplos en el FTP, y la búsqueda en los foros ;)

bulc 23-05-2013 20:54:37

Touché... miro, miro, miro....miro, miro
 
Cita:

Empezado por Casimiro Notevi (Mensaje 461123)
Amigo bulc, ¿recuerdas el libro que te indiqué?, ¿y los tutoriales?, y los ejemplos en el FTP, y la búsqueda en los foros ;)

Bueno, Me pongo a mirar ese material. Y si no encuntro nada....

Casimiro Noteví 23-05-2013 21:02:03

Cita:

Empezado por bulc (Mensaje 461126)
Bueno, Me pongo a mirar ese material. Y si no encuntro nada....

Lo encontrarás :)

Ten en cuenta que si quieres aprender no te queda otra. Porque supongo que quieres aprender y dedicarte a esto.
En cuanto veas un poco del libro te darás cuenta que ese código que has puesto es "una patata" de aficionadillo, si quieres ser profesional entonces a leer ;)

oscarac 24-05-2013 08:06:13

Casimiro tiene razon
ese codigo es muy engorroso
no es necesario habilitar el grid ni los datasources, cuando se conectan se activan implicitamente al abrir el query

mas o menos lo q tienes q hacer es esto
el grid asignarle un datasource, el mismo q esta asignado al query
abres el query y listo, la informacion deberia verse en el grid
salvo el parametro colocado sea incorrecto en consecuencia no muestre dato alguno

bulc 24-05-2013 11:38:17

El IBQuery por letra inicial funciona perfectamente...
 
Ese TiBquery funciona perfectamente, sólo tiene de exceso que el Provider, el DataSource y Grid no intervienen en la transaccion.
Es obligatorio cerrar y volver a abrir el IQquery y el ClientDataSet. Además de vaciar el SQL, claro.
He probado con la propiedad Prepare. Pero creo que el quid está en la propiedad Params del IBQuery...
Ahora bien, puse todos los componentes de la aplicación (en el código) para ver si eran necesarios o no. Ya que habia observado que un cambio en la prop. IBQuery.SQL afectaba a otros componentes. El nudo de la cuestión es que yo -en plan novato- uso un TTabControl con 26 letras. Al clicar una letra cambia el acceso al Query y se ven únicamente los registros que empiezan por esa letra. (Ten en cuenta que la base de datos gurda dibujos para usar en aplicaciones didácticas). El caso es que me planteé cambiar el TabControl por un acceso
al TQuery con parámetros. He mirado en un buen puñado de libros y en la red. Intuyo que lo que hace el servidor es crear un campo virtual con el parámetro, de manera que se pueda usar como enlace a los datos. Esto se hace modificando la prop. Params del IBQuery. Pero ahí te solicita unos datos que no consigo enderezar. Pero, vaya, estoy en ello. Ya he revisado el libro de Mareens (CaraOculta6) y ahora estoy con CaraOculta4. Sé que lo conseguiré de un modo u otro. Pero me llevará un tiempo. Como estoy jubilado me lo tomo con calma. No vivo de esto. Lo tengo como afición.
¿Alguien hace accesos a los registros por la primera letra (a,b,c...) de un campo indexado usando IBQuery con parámetros?
Si sabéis algo del famoso IBQuery, usado con parámetros, pues vuestra ayuda es bienvenida.

bulc 24-05-2013 11:41:24

Cita:

Empezado por Casimiro Notevi (Mensaje 461128)
Lo encontrarás :)

Ten en cuenta que si quieres aprender no te queda otra. Porque supongo que quieres aprender y dedicarte a esto.
En cuanto veas un poco del libro te darás cuenta que ese código que has puesto es "una patata" de aficionadillo, si quieres ser profesional entonces a leer ;)


Ya estoy jubilado con cuarenta años de servicios... Y te aseguro que bien currados. Me dedico a esto porque me gusta. Es una afición.... también toco la guitarra.

Casimiro Noteví 24-05-2013 12:03:21

Cita:

Empezado por bulc (Mensaje 461169)
Ya estoy jubilado con cuarenta años de servicios... Y te aseguro que bien currados. Me dedico a esto porque me gusta. Es una afición.... también toco la guitarra.

Yo también me "jubilaré" pronto :D

Para lo que quieres, es sencillo, es lo más básico, una plantilla/esquema sería algo así:
Usa un dataset, no el ibquery, te resultará más cómodo.
Este es el select del ibdatset:
Código SQL [-]
ibdatset.selectsql.text="select * from tabla where campo starting with :letra";
Ahora, en el evento de cambio de pestaña escribes:
Código SQL [-]
ibdatset.close;
ibdatset.params[0].value := laletraquesea /* no sé cómo lo estás haciendo */
ibdatset.open;
Se acabó.

Si estás jubilado entonces puedes leer tranquilamente el libro :D


pd: he escrito el código más o menos de memoria.

bulc 24-05-2013 12:53:57

Cita:

Empezado por Casimiro Notevi (Mensaje 461170)
Yo también me "jubilaré" pronto :D

Para lo que quieres, es sencillo, es lo más básico, una plantilla/esquema sería algo así:
Usa un dataset, no el ibquery, te resultará más cómodo.
Este es el select del ibdatset:
Código SQL [-]
ibdatset.selectsql.text="select * from tabla where campo starting with :letra";
Ahora, en el evento de cambio de pestaña escribes:
Código SQL [-]
ibdatset.close;
ibdatset.params[0].value := laletraquesea /* no sé cómo lo estás haciendo */
ibdatset.open;
Se acabó.

Si estás jubilado entonces puedes leer tranquilamente el libro :D


pd: he escrito el código más o menos de memoria.

Pero, ¿no tengo que ajustar el parámetro en la propiedad Params del Query? Es por donde estaba hurgando...
Quiero decir; ¿ no se deben establecer los Parámetros con antelación (en diseño o en runtime)?
De todos modos cambiaré el IBQuery por un TIBDataSet, como recomiendas. ¿Quito el Provider y el ClientDataSet ?
Gracias.
Tal como están las cosas, te queda un pico para la jubilation.

ecfisa 24-05-2013 17:48:15

Hola bulc.

Cita:

Empezado por bulc (Mensaje 461174)
Pero, ¿no tengo que ajustar el parámetro en la propiedad Params del Query? Es por donde estaba hurgando...
Quiero decir; ¿ no se deben establecer los Parámetros con antelación (en diseño o en runtime)?

Si por supuesto.

Cita:

Empezado por bulc (Mensaje 461174)
¿Quito el Provider y el ClientDataSet ?

Para lo que deseas hacer no son necesarios.

Como te dijo Casimiro, es muy sencillo de realizar con ambos componentes.

Usando TIBQuery:
Código Delphi [-]
...
begin
  ...
  with IBQuery1 do
  begin
    Close;
    SQL.Text := 'SELECT * FROM WB WHERE ITEM STARTING WITH :cInicial'; 
    ParamByName('cInicial').AsString := cIni;
    Open;
  end;
end;

Usando TIBDataSet:
Código Delphi [-]
begin
  ...
  with IBDataSet1 do
  begin
    Close;
    SelectSQL.Text := 'SELECT * FROM WB WHERE ITEM STARTING WITH :cInicial';
    ParamByName('cInicial').AsString := cIni;
    Open;
  end;
end;
La ventaja del TIBDataSet es que dando valor a la propiedad SelectSQL en diseño, te permite usar la herramienta DataSetEditor, con la que podrás generar con muy poca intervención las sentencias para insertar, modificar y borrar datos. Esto no es así para el TIBQuery donde tendrás que definir las sentencias manualmente.

También remarco la sugerencia que te hizo Casimiro en otro mensaje sobre revisar el tutorial del amigo Caral: Tutorial

Saludos. :)

bulc 24-05-2013 21:18:05

Gracias, Ecfisa. Realmente ese tutorial no me resulta adecuado. Lo doy por superado. Pero agradezco tu empeño y aclaración.
Estoy dando un repaso a los libros. Ojalá fueran de papel... pero sigo adelante. Más pronto que tarde daré con la solución. Seguro.
Hasta pronto, amigos.
Bulc-anizado

Casimiro Noteví 24-05-2013 21:45:58

Cita:

Empezado por bulc (Mensaje 461206)
Gracias, Ecfisa. Realmente ese tutorial no me resulta adecuado. Lo doy por superado. Pero agradezco tu empeño y aclaración.

Para nada, amigo, si dices eso es que no has visto el tutorial :confused:

bulc 25-05-2013 14:03:26

Parametros con Query. Mi explicación
 
Cita:

Empezado por Casimiro Notevi (Mensaje 461208)
Para nada, amigo, si dices eso es que no has visto el tutorial :confused:

Exiten dos tipos de acceso a Parámetros, en diseño y con código. Para usarlos en diseño se recurre a la propiedad Params del Query. Se abre su editor y
aparece su ventana. Debemos asignar Type: String; Nombre del Parametro: INI y su valor Unknown. Luego en código podemos hacer referencia a él a
través de QueryX.Params[0] asignandole el valor actual. Previo a esto debemos cerrar el query(Close), limpiarlo Query.Clear, asignar el parámetro Params[0].Value:=cXX, asignar al SQL statement "SELECT campos FROM table WHERE campo = :INI ".
Al abrir de nuevo el query se le asignará es valor del select parametrizado. No debemos olvidar si el valor del Query pasa a un ClientDataset de cerrar y abrir este también para que se renueven los datos que este último envía al DataSource que a su ve los pasa al DBGrid.
Si es por código debemos usar un valor más exacto al parámetro, para ello nos apoyamos en un campo explícito. Para esto usamos la localización del parámetro. Query1.ParamByName('ParamName').AsMoldeador:='ValorActuall';
Pero, y a pesar de la teoría, no funciona. Tampoco da error. En mi caso el Query carga todos los registros con la cual, despues de un momento, el ClientDataSet da el error 'Infufcient Memory for this Operation".
Fíjate en esto. Coloco un TTabControl con todas las letras del alfabeto. Lo uso y se puede acceder 'A TODA LA TABLA' por la letra que se elija.
Tiene que haber algún pequeño (o gran) error que impide usar el parámetro. Usaré el debugger hasta dónde yo sé y luego como plan b. Usaré dos dbGrid
separando uno para el Query y otro para el ClientDataSet. En fin, que ya caeré del burro. Tranquilo, Casimiro. Y deja de poner en duda lo que te digo, por favor. Trabajo en equipo. Excusas si causo un conflicto.
Por cierto, las subpropiedades de la Prop. Params del Query me dejan un poco al pairo. ¿Se pueden explicar aqui?
Gracias por todo.

Casimiro Noteví 25-05-2013 14:44:01

¿Estás usando el código que te ha puesto ecfisa?

bulc 25-05-2013 19:38:30

IBQuery con parámetro; solucionado
 
Aprovechando tu tesón hice una prueba creando el Parametro usando la prop. Params en diseño. Después de toquetear con el InputOutput, funcionó.
Así que la pasé a código en runtime. Tenía un error de entrada. La recogida del dato estaba vacía. Puse un InputQuery y ya funciona.
Este es mi código final. Un poco pardillo, pero funciona.
Os quería hacer una pregunta que para mi tiene mucha importancia. Veréis. En la interface de mi tabla es importante que se vea un gráfico con cada registro. Para no consumir recursos uso la selección de los registros por letra inicial. Va bien, pero en el supuesto de muchos registro me gustaría poder
ver los registro de cien en cien o de 50 en 50. ¿Qué sistema es el más usado, el de letra o el de una cantidad x de registros?.
Y por otra parte os pongo un sobresaliente, y os agradezco vuestra paciencia con un latoso como yo.
Código Delphi [-]
procedure TPictures1.BitBtnBusca2Click(Sender: TObject); //Parameter
Var
cINI : String ;
begin
InputQuery('Introduzca la letra inicial: ', 'Letra:', cIni );
//Try to use Parameters:
   IBQuery1.Close;
   cIni:=trim(cINI);
   ShowMessage('Letra  : ' + cINI ); //Control de la entrada. Provisional
   ClientDataSet1.Active:=False; //. Close válido.

   IBQuery1.SQL.Clear;
   IBQuery1.SQL.Add('SELECT * FROM WB WHERE ITEM STARTING WITH :INI  ');
   //IBQuery1.ParamByName('INI').AsString:= cINI ; //Válido
   IBQuery1.Params[0].Value := cINI ;  // Válido

   IBQuery1.Open;
   ClientDataSet1.Active:=True;
 end;

ecfisa 26-05-2013 01:29:32

Cita:

Empezado por bulc (Mensaje 461232)
Por cierto, las subpropiedades de la Prop. Params del Query me dejan un poco al pairo. ¿Se pueden explicar aqui?

Hola bulc.

A ver si puedo aclarar un poco el asunto...

Los parámetros se definen en la consulta y siempre se escriben precedidos por dos puntos ':'. La consulta se puede asignar en tiempo de diseño o en tiempo de ejecución.

Si en tiempo de diseño, desde el Object Inspector, asignamos a la propiedad SQL el valor:
Código SQL [-]
SELECT * 
FROM TABLA
WHERE NAME = :PNAME
Se habrá creado un parámetro llamado "PNAME", cosa que podes comprobar desde el mismo Object Inspector haciendo click sobre los '...' de la propiedad Params.

Habiendo sido creada la consulta y su parámetro, se puede llamar bién por su propiedad vectorial Params:
Código Delphi [-]
  with IBQuery1 do
  begin
    Close;
    Params[0].AsString := Edit1.Text;
    Open;
  end;
O bién mediante el método ParamByName:
Código Delphi [-]
  with IBQuery1 do
  begin
    Close;
    ParamByName('PNAME').AsString := Edit1.Text;
    Open;
  end;


De otro modo, si consulta y parámetro son creados en tiempo de ejecución, se deben especificar ámbos.

Mediante la propiedad vectorial Params:
Código Delphi [-]
  with IBQuery1 do
  begin
    Close;
    SQL.Text := 'SELECT * FROM TABLA WHERE NAME = :PNAME';
    Params[0].AsString := Edit1.Text;
    Open;
  end;
Mediante el método ParamByName:
Código Delphi [-]
  with IBQuery1 do
  begin
    Close;
    SQL.Text := 'SELECT * FROM TABLA WHERE NAME = :PNAME';
    ParamByName('PNAME').AsString := Edit1.Text;
    Open;
  end;

Existe un tercer modo de acceso a los parámetros y es mediante la propiedad ParamValue:
Código Delphi [-]
  with IBQuery1 do
  begin
    Close;
    SQL.Text := 'SELECT * FROM TABLA WHERE NAME = :PNAME';
    Params.ParamValues['PNAME'] := Edit1.Text;
    Open;
  end;

Por último cabe acotar que si existe una definición de consulta/parámetros en tiempo de diseño, al asignar una nueva definición de consulta/parámetros en tiempo de ejecución, se sobreescribirá lo realizado en tiempo de diseño.

Saludos. :)

bulc 26-05-2013 18:09:48

Gracias por la aclaración. la he leído con interés
 
Gracias, Ecfisa por tu explicación. Al final he conseguido que funcione gracias a vuestra ayuda. Opté por usar el parámetro en tiempo de diseño y como
te comento (después de hurgar con el tipo entrada-salida), funcionó.
Posteriormente lo pasé todo a runtime, por código.
Un abrazo,
Bulc


La franja horaria es GMT +2. Ahora son las 19:10:06.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi