PDA

Ver la Versión Completa : Query en procedimiento


antigrondona
23-04-2012, 15:26:38
Hola amigos, mi problema es que utilizo los query (adoquery) en procedimientos para luego invocarlos. Como esas rutinas van en una unidad no incorporo los componentes (adoquery) a los formularios, entonces lo que quiero hacer es utilizar los query como variables locales y devolver el resultado en alguna otra. Me están dando dolores de cabeza, al compilar hay errores en memoria.
Lo que hago es más o menos lo siguiente

var
query1,query2:TADOquery; las declaro

luego las creo con query1.TADOQuery.Create(query1) y hago la consulta.

Seguro que me falta algo, además quisiera liberar la var al finalizar (query1.free), pero también me dió problemas.

Saludos, espero respuestas.

roman
23-04-2012, 16:12:19
query1.TADOQuery.Create(query1)

¿Por qué no pones exactamente cómo es que creas el componente. Esta sentencia que pones es imposible.

// Saludos

Northern
24-04-2012, 12:58:35
Hola amigos, mi problema es que utilizo los query (adoquery) en procedimientos para luego invocarlos. Como esas rutinas van en una unidad no incorporo los componentes (adoquery) a los formularios, entonces lo que quiero hacer es utilizar los query como variables locales y devolver el resultado en alguna otra. Me están dando dolores de cabeza, al compilar hay errores en memoria.
Lo que hago es más o menos lo siguiente

var
query1,query2:TADOquery; las declaro

luego las creo con query1.TADOQuery.Create(query1) y hago la consulta.

Seguro que me falta algo, además quisiera liberar la var al finalizar (query1.free), pero también me dió problemas.



Imagino que con ese "van en una unidad" te refieres a que todos los componentes no visuales de acceso a datos (TADOConnection, TDataSource, TADOTable, TADOQuery, etc. ) los colocas en el DataModule. No ?

Después enlazas esa unidad, la del DataModule, a los Forms en los que quieres consultar/editar/agregar/borrar datos.

Finalmente para acceder a los datos de la BD limpias la consulta previa, añades una consulta, preparas la consulta y la abres, entre otros detalles...

Si no lo haces así, te estás liando demasiado. Además un único TQuery vale para realizar muchísimas consultas las cuales no todas tienen que estar abiertas al mismo tiempo.

No sé, yo me replantearía eso de crear componentes de acceso a datos en tiempo de ejecución en vez de en tiempo de diseño.

olbeup
25-04-2012, 08:55:19
Antes lo hacia en un DataModule, al poco tiempo me faltaba pantalla para poner los componentes de base de datos, al final opte por crear los componentes en tiempo real y no me arrepiento de haberlo hecho.

Este proceso lo realizo en cada formulario y nos es más trabajo, sino otra forma de trabajar, para mi, es ideal.

Primero, Definir en TForm:
...
private
{ Private declarations }
SQLInitDB: TStrings; <-- Aquí introduzco la SQL

// Variable de búsqueda
SQLWhereText: TStrings; <-- Aquí los parametros de WHERE

// Componente de Conexión Facturas
adoCnnFrm: TADOConnection;
adoQryFrm: TADOQuery;
dsSrcFrm: TDataSource;

...
...
end;


Segundo, Cuando se crea el TForm:
...
begin
adoCnnFrm := TADOConnection.Create(Self);
adoCnnFrm.LoginPrompt := False;
adoCnnFrm.ConnectionString := MSSQLServerCfg.ConnectionString; <-- Parámetro que se le pasa para la Conexión

adoQryFrm := TADOQuery.Create(Self);
adoQryFrm.Connection := adoCnnFrm;

dsSrcFrm := TDataSource.Create(Self);
dsSrcFrm.DataSet := adoQryFrm;

dbgGrid.DataSource := dsSrcFrm;

SQLInitDB := TStringList.Create;
SQLInitDB.Add('SELECT');
SQLInitDB.Add(' ...');
SQLInitDB.Add(' ...');
SQLInitDB.Add(' FROM xxyyzz');

SQLWhereText := TStringList.Create;
end;


Tercero, Cuando se busca
...
var
FieldValue: Integer;
begin
// Guarda la posición del Grid, para después recuperarlo.
FieldValue := GetIDxxyyzzGrid;

// Comprobar que la base de datos si está abierta y cerrarla
if adoCnnFrm.Connected then
adoCnnFrm.Close;

with adoQryFrm do
begin
SQL.Clear;

SQL.Assign(SQLInitDB);

if (SQLWhereText.Count > 0) then
SQL.Add(SQLWhereText.Text);

Open;
end;

// Se pone ésta línea para que el puntero se actualice en el Grid
// si no se pone el metodo (Update) del DBGrid, el puntero estaría
// actualizado pero el foco que es azul estaría en la parte superior
// del grid, y eso, lleva a confusión de donde se encuentra el puntero.
dbgGrid.Update;

// Posicionar el puntero donde estaba
with dbgGrid.DataSource.DataSet do
begin
Locate('IDXXYYZZ', FieldValue, [loCaseInsensitive]);
Result := RecordCount;
end;
end;


Cuarto, Cuando se cierre el formulario
...
begin
SQLInitDB.Free;
SQLWhereText.Free;

adoCnnFrm.Free;
dsSrcFrm.Free;
adoQryFrm.Free;
end;


Y esto me va muy bien.

Un saludo.

antigrondona
25-04-2012, 13:42:24
¿Por qué no pones exactamente cómo es que creas el componente. Esta sentencia que pones es imposible.

// Saludos

Perdón, es verdad, la puse mal y es imposible.

query1:=TADOQuery.Create(query1);

asi la creo en tiempo de ejecución y luego hago la consulta. Evidentemente no se crea adecuadamente porque me dá error en memoria al invocar el procedimiento.

A los demás gracias por sus recomendaciones, pero trabajo incorporando procedimientos en una Unit auxiliar, de esa forma solo debo invocarlos en lugar de repetir codigo.

roman
25-04-2012, 17:20:49
query1:=TADOQuery.Create(query1);


Esto es incorrecto. No puedes pasar como parámetro al Create al propio componente. Si tú mismo(a?) vas a destruir posteriormente el componente, pasa nil como parámetro.

// Saludos

antigrondona
26-04-2012, 13:53:24
Esto es incorrecto. No puedes pasar como parámetro al Create al propio componente. Si tú mismo(a?) vas a destruir posteriormente el componente, pasa nil como parámetro.

// Saludos

Oka, podrías decirme por favor como es la sentencia?

Delphius
26-04-2012, 14:47:50
Oka, podrías decirme por favor como es la sentencia?
¿Tan dificil es entender lo que dijo roman?

Query1 := TADOQuery.Create(nil);

Saludos,

antigrondona
26-04-2012, 15:10:09
¿Tan dificil es entender lo que dijo roman?

Código Delphi [-] (http://clubdelphi.com/foros/#)Query1 := TADOQuery.Create(nil);


Saludos,

Utilizo esa linea, luego hago la consulta y finalmente query1.free?

Gracias.

Delphius
26-04-2012, 15:14:08
Si, necesitas TU MISMO liberarlo.

Cuando tu defines en el parámetro que el dueño sea nil le estás indicando que tu eres quien se encargará de liberarlo y no la aplicación.
Te recomiendo la lectura de la ayuda, allí está aclarado el asunto.

Saludos,