PDA

Ver la Versión Completa : Limitar registros de un IBDataSet según un StringList en memoria


gluglu
28-06-2007, 11:52:35
Hola compañeros del foro !

Como podría limitar mostrar sólo los registros de un Query a aquellos cuya clave esté contenida en un StringList que manejo en memoria ??

Tengo una lista de selección para elegir aquellas claves que quiero imponer como condición en otra consulta. Esa lista la manejo mediante un StringList en memoria ya que cada usuario activo puede elegir un conjunto de claves diferente en un momento determinado.

Y lo que pretendo es que en la otra consulta que muestro, sólo aparezcan aquellos registros cuya clave concreta haya sido seleccionada por el usuario, es decir, que esté contenida en el StringList.

Entiendo que sería inmediato grabar todos esas claves seleccionadas en una base de datos (temporal o no) y hacer un nuevo Select con la condición de que la clave estuviera contenida en dicha tabla. Pero vuelvo a comentar el problema de cada usuario e incluso de que cada usuario pudiera a la vez tener abiertas varias consultas con condiciones diferentes. Debería entonces gestionar eso a nivel de la tabla que indico.

Por eso preguntar si alguien tiene una solución diferente.

Gracias por vuestra ayuda. ;)

mamaro
28-06-2007, 16:31:20
Hola que tal, creo que se podría construir la consulta de forma dinámica levantando el filtro de el stringlist, por ejemplo supongamos que en el stringlist almacenas los campos clave, que para el ejemplo vamos a decir que son integer:

// Retorna un string con la consulta a ejecutar
function Crea_Filtro:string;
var x:integer;
aux:string;
begin
aux:='';
if (strlis.count>0) then begin
aux:='campoclave='+strlis[0]+')';
if (strlis.count>1) then
for x:= 1 to (StrLis.count-1) do begin
aux:=aux+' or (campoclave='+strlis[x]+')';
end;
end;
result:=aux;
end;

function Crea_Consulta:string;
var aux:string;
begin
result:='Select * from Tabla';
aux:='';
aux:=Crea_Filtro;
if (length(aux)>0) then begin
result:=result+' where '+aux;
end;
end;

Por lo que la función Crea_Consulta te retorna la consulta que debes ejecutar, o sea haces algo así como:

..
DataSet.close; // por si lo tenías abierto de antes
DataSet.SQL.clear;
DataSet.SQL.text:=Crea_Consulta;
DataSet.open;
..

Saludos y cruzo los dedos para que funcione (no lo probé) ;)

gluglu
28-06-2007, 16:42:39
Gracias por contestar.

Pues si, sería una posible solución. Lo que pasa es que el texto del Select de la consulta podría crecer mucho. Y no sé como afectaría a la velocidad de la consulta.

Voy a tenerlo en cuenta aunque sigo ideando otras soluciones. Ya avisaré como quedó. :rolleyes:

gluglu
28-06-2007, 17:31:51
Al final opté por la solución que pensé al principio.

Hacer uso de una base de datos 'temporal' (en el sentido figurado de la palabra, aunque permanente para Interbase), en la cual antes de generar la consulta SQL, inserto las 'Claves' que necesito localizar, y dentro de la consulta SQL general hago una subconsulta de esta tabla 'temporal' para limitar la clave que busco a las claves contenidas en los registros de esa tabla 'temporal'.

Como se trata de una consulta únicamente, al estar asociadas ambas tablas, la de consulta principal y la de la tabla 'temporal', a la misma transacción que creo sólo para dicha consulta, al cerrar la transacción y no necesitar de ningún commit en mi operativa, todos los registros creados hasta ese momento se eliminarán.

He optado por esta solución ya que la consulta principal en sí misma, la genero de manera dinámica en tiempo de ejecución, y debido a que pueden existir otros muchos parámetros condicionales, la longitud de la misma consulta se podría extender demasiado y afectar al rendimiento de la misma.

ClNaU2 a todos ;)