Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 08-03-2008
Avatar de eduarcol
[eduarcol] eduarcol is offline
Miembro Premium
 
Registrado: ago 2003
Ubicación: En los estados Zulia y Merida de Venezuela
Posts: 4.151
Poder: 25
eduarcol Va por buen camino
Tabla que llena un query

Hola a todos, estoy trabajando con los componentes ZEOS, base de datos Firebird y Delphi 7. Me conecto por medio de un Query pero este query es muy dinamico, puede ser utilizado para mostrar informacion de cualquier tabla, aqui viene el problema: Yo puedo recuperar todos los campos que devuelve la consulta por medio del FieldDefs, lo que me falta saber es por medio de que propiedad puedo recuperar la tabla o tablas que llena esta Query?

Gracias por leerme
__________________
...Yo naci en esta ribera del arauca vibr@d0r
Soy hermano de la espuma,
de la garza, de la rosa y del sol...
Viva Venezuela
Responder Con Cita
  #2  
Antiguo 08-03-2008
Avatar de yusnerqui
yusnerqui yusnerqui is offline
Miembro
 
Registrado: mar 2004
Ubicación: Cuba
Posts: 679
Poder: 21
yusnerqui Va por buen camino
La query está creada en la base de datos o la generas tú??, estoy pensando en parsear el texto de la propiedad sql.text y de ahí sacar las tablas
__________________
Lo importante no es llegar primero, sino saber llegar.

Para que puedas llegar mejor lee la Guia de Estilo

Responder Con Cita
  #3  
Antiguo 08-03-2008
Avatar de gluglu
[gluglu] gluglu is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Málaga - España
Posts: 1.455
Poder: 21
gluglu Va por buen camino
Código Delphi [-]
Aux_SelectSQL1 := '';
Aux_SelectSQL2 := UpperCase((DataSet as TIBDataSet).SelectSQL.Text);

for j := 1 to Length(Aux_SelectSQL2) do begin
  if Aux_SelectSQL2[j] = #13 then
    Aux_SelectSQL1 := Aux_SelectSQL1 + ' '
  else
    if Aux_SelectSQL2[j] <> #10 then
      Aux_SelectSQL1 := Aux_SelectSQL1 + Aux_SelectSQL2[j];
end;
 
Aux_Pos := 1;
while PosEx(' FROM', Aux_SelectSQL1, Aux_Pos) <> 0 do begin
  Aux_Pos := PosEx(' FROM', Aux_SelectSQL1, Aux_Pos) + 1;
end;
 
Dec(Aux_Pos);
Aux_Table  := Copy(Aux_SelectSQL1, Aux_Pos+6, PosEx(' ', Aux_SelectSQL1, Aux_Pos+6) - (Aux_Pos+6));

El nombre de la tabla lo tendrás finalmente en Aux_Table.



P.D. He obviado el código correspondiente a la declaración de variables.
__________________
Piensa siempre en positivo !
Responder Con Cita
  #4  
Antiguo 08-03-2008
Avatar de eduarcol
[eduarcol] eduarcol is offline
Miembro Premium
 
Registrado: ago 2003
Ubicación: En los estados Zulia y Merida de Venezuela
Posts: 4.151
Poder: 25
eduarcol Va por buen camino
Pues lo que pensaron ustedes es como lo tengo en estos momentos, solo queria asegurar que no hubiese una propiedad del dataset que guarde la lista de las tablas involucradas

Código Delphi [-]
cTablas := Copy(sq.SQl.Text, Pos('from', sq.SQl.Text) + 4, Length(sq.SQl.Text));
   cTablas := Copy(cTablas, 1, Pos('where', cTablas) - 1);

ahora con el monstruo de codigo que coloco gluglu, me puse a sudar, para que es la comparacion con #13 o #10??
__________________
...Yo naci en esta ribera del arauca vibr@d0r
Soy hermano de la espuma,
de la garza, de la rosa y del sol...
Viva Venezuela
Responder Con Cita
  #5  
Antiguo 09-03-2008
Avatar de gluglu
[gluglu] gluglu is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Málaga - España
Posts: 1.455
Poder: 21
gluglu Va por buen camino
Al menos yo, utilizo en algunos casos sentencias SQL muy largas que por supuesto detallo en varias líneas, y estas líneas incluyen entonces un #13#10 para salto de línea.

Es por ello que para parsear la sentencia SQL correspondiente al Select elimino previamente esos saltos de línea y los convierto en blancos (' ') para obtener un único string a parsear posteriormente.

Y quiero añadir que tu código no sería correcto en varios casos :

1. Que en algún momento decidieras hacer uso de mayúsculas/minúsculas en tu texto SQL. Por eso convierto previamente todo a caracteres mayúsculas con Upper. No recuerdo en estos momentos excatamente si en caso de no hacerlo así, y dejando los saltos de línea, las funciones Copy, Pos y PosEx devuelven valores con sentido. Supongo que en su momento lo analizé y ví que era así, que dichas funciones devuelven valores raros si por medio hay #13#10 de saltos de línea.

2. Que alguno de tus campos de la tabla haya sido nombrado con algun nombre que contenga 'from' como parte del nombre. (Ej. : se me ocurre ahora mismo la palabra 'fromage', que significa queso en francés).

Select fromage from mi_tabla_de_fromages

En este caso tu código detectaría la 1ª aparición de 'from' en los nombres de los campos de la tabla y no el nombre de tabla que estás buscando.

Es por ello que deberías buscar la última aparición de ' from', con un espacio delante, ya que si 'from' está a su vez contenido en el propio nombre de la tabla, si no buscas con el espacio delante, tampoco obtendrás el nombre de la tabla.

Por ello incluí el bucle expresado en mi código utilizando PosEx.

3. Tu código tampoco funcionaría correctamente si utilizas un 'alias' para el nombre de la tabla.

Select fromage from mi_tabla_de_fromages mtdf where fromage = 1

(je je ... me acabo de dar cuenta que mi código tampoco funciona 100% ... Ahora después me pondré a corregirlo y tener en cuenta las apariciciones de ' from' después de un where ).

No debes de buscar el nombre de la tabla hasta el próximo 'where' porque puede haber un alias en medio. Deberás buscar desde la correcta aparición de ' from' hasta el siguiente espacio en blanco para ignorar el alias.

Además, por supuesto que se pueden dar multitud de ocasiones de sentencias SQL que no contengan ninguna condición 'where', por lo que dicha palabra ni siquiera aparecerá en la sentencia SQL y tu código tampoco sería correcto.

En cualquier caso, también habría que tener en cuenta que 'where' también pudiera formar parte de cualquier nombre de campo.


Como verás, finalmente no es asunto tan fácil como cabría pensar.

Espero no haberte 'desmoralizado' con las múltiples posibilidades de fallo de tu código.
__________________
Piensa siempre en positivo !

Última edición por gluglu fecha: 09-03-2008 a las 11:31:31.
Responder Con Cita
  #6  
Antiguo 09-03-2008
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Aquí un humilde TSelectString para crear al vuelo y modificar los sqls.

Se trata de trocear un Sql en Secciones ( el select, el from, el where, etc), poder acceder a cada una de ellas y modificarlas con algo de comodidad.

Código Delphi [-]
var ss: TSelectString;
begin
  ss := TSelectString.Create;
  ss.text := 'select * from tabla where nombre = ' + edit2.text;

  if BuscaApellido then
    ss.AddToWhere(oAnd, 'apellido = '+edit1.text);

  if ordenaApellido then
    ss.AddToSection(pOrderBy, 'Apellido Desc');


  ShowMessage(ss.Text);
  query1.sql.text := ss.text;
  ss.Free;
  query1.open;

ss.Sections[pFrom] --> te devolverá desde la palabra "FROM " hasta el "where " (o el final del sql);

No es una versión definitiva, pero algo es algo.

Edito:
- hay algunas unidades que no las tendréis, borrarla del uses, no las utiliza.
- "saltolinea" es una constante definida como const saltolinea = #13#10
- Creo eso es todo....


Saludos
Archivos Adjuntos
Tipo de Archivo: zip lpSql.zip (2,8 KB, 10 visitas)
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.

Última edición por Lepe fecha: 09-03-2008 a las 12:01:42.
Responder Con Cita
  #7  
Antiguo 09-03-2008
Avatar de gluglu
[gluglu] gluglu is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Málaga - España
Posts: 1.455
Poder: 21
gluglu Va por buen camino
Ya creo que lo tengo correctamente :

Código Delphi [-]
Aux_SelectSQL1 := '';
Aux_SelectSQL2 := UpperCase((DataSet as TIBDataSet).SelectSQL.Text);

for j := 1 to Length(Aux_SelectSQL2) do begin
  if Aux_SelectSQL2[j] = #13 then    Aux_SelectSQL1 := Aux_SelectSQL1 + ' '
  else
    if Aux_SelectSQL2[j] <> #10 then
      Aux_SelectSQL1 := Aux_SelectSQL1 + Aux_SelectSQL2[j];
end;
 
Aux_Pos := 1;
while PosEx(' FROM ', Aux_SelectSQL1, Aux_Pos) <> 0 do begin
  Aux_Pos := PosEx(' FROM ', Aux_SelectSQL1, Aux_Pos) + 1;
end;
 
Dec(Aux_Pos);
Aux_Table  := Copy(Aux_SelectSQL1, Aux_Pos+6, PosEx(' ', Aux_SelectSQL1, Aux_Pos+6) - (Aux_Pos+6));

Bastaba con buscar 'from' como palabra 'reservada'. Es decir, basta con buscar ' from ' con espacio delante y detrás.

Y revisando el código, me dí cuenta de otra particularidad que no mencioné anteriormente : las subconsultas !

Select fromage, (Select loquesea from mi_otra_tabla where loquesea = 1) from mi_tabla_de_fromages mtdf where fromage = 1

Por eso lo de localizar la última aparición de ' from ' en la sentencia SQL.

Saludos
__________________
Piensa siempre en positivo !
Responder Con Cita
  #8  
Antiguo 09-03-2008
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Tienes razón, el TSelecStrings no tiene en cuenta las subconsultas (yo no las uso mucho) .

Ahora que lo pienso:
Código SQL [-]
select  nombre, (select distinct edad from edades)
from tabla
where  edad < (select edad from edades)

... amos, que si nos ponemos a buscarle fallos, no terminamos.

Por suerte y sin tenerlo programado, puedes armar la consulta como:
Código Delphi [-]
ss.Sections[pSelect] := 'nombre, (select distinct edad from edades)';
ss.Sections[pFrom] := 'tabla';
ss.AddToWhere(oNull, 'edad < (select edad from edades)');

Por cierto guglu, deja de chatear conmigo

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.

Última edición por Lepe fecha: 09-03-2008 a las 12:16:25.
Responder Con Cita
  #9  
Antiguo 09-03-2008
Avatar de eduarcol
[eduarcol] eduarcol is offline
Miembro Premium
 
Registrado: ago 2003
Ubicación: En los estados Zulia y Merida de Venezuela
Posts: 4.151
Poder: 25
eduarcol Va por buen camino
Hola y gracias por la ayuda, me ha servido de mucho, no me desmoraliza las fallas ya habia analizado una serie de escenarios y se que no funcionaria a la perfeccion. Por eso buscaba alguna propiedad magica, que me delvoviera las tablas involucradas.

Yo creo una pantalla de busqueda generica: Una caja de texto, un Grid, un boton y un query, en la inicializacion del form paso como parametro la sentencia que quiero mostrar y automaticamente se arma el grid con la informacion resultante de la consulta. Al darle el boton aceptar devuelve el valor del campo en la posicion 0.

Ahorita doy la opcion con un filtro de ir buscando el registro que coincida con lo que se escribe en la caja de texto. Pero como se quiere acceder por medio de internet es muy lento debido a que hay que cargar todos los registros. Lo que pretendo es relanzar la consulta que lleno la tabla con los filtros establecidos por el usuario. Es decir, la primera pudo haber sido por el nombre, luego por el apellido, pense hacerlo como algo parecido a como sugirio Lepe, tres variables: Campos, Tablas y condicion y armar el sql algo asi:

Código Delphi [-]
'Select ' + Campos + ' from ' + Tablas + ' where ' + Condicion

pero tambien le doy a los usuarios avanzados la capacidad de crear sus propias consultas sql.

Bueno espero haberme explicado y usare las sugerencias obtenidas. Muchas gracias a todos por sus acertadas participaciones.

Saludos
__________________
...Yo naci en esta ribera del arauca vibr@d0r
Soy hermano de la espuma,
de la garza, de la rosa y del sol...
Viva Venezuela
Responder Con Cita
  #10  
Antiguo 09-03-2008
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Hola
No se si con zeos se podrá hacer esto, pero Roman me enseño a hacer un filtro de selección por tablas y campos, revisalo, tal vez te de ideas.
Saludos
Responder Con Cita
  #11  
Antiguo 09-03-2008
Avatar de eduarcol
[eduarcol] eduarcol is offline
Miembro Premium
 
Registrado: ago 2003
Ubicación: En los estados Zulia y Merida de Venezuela
Posts: 4.151
Poder: 25
eduarcol Va por buen camino
Algo parecido estoy haciendo amigo Carlos, pero no puedo trabajar con Filtros porq al traer todos los registros por internet se haria insorpotable la lentitud al abrir la pantalla de busqueda.
__________________
...Yo naci en esta ribera del arauca vibr@d0r
Soy hermano de la espuma,
de la garza, de la rosa y del sol...
Viva Venezuela
Responder Con Cita
  #12  
Antiguo 27-03-2008
Avatar de eduarcol
[eduarcol] eduarcol is offline
Miembro Premium
 
Registrado: ago 2003
Ubicación: En los estados Zulia y Merida de Venezuela
Posts: 4.151
Poder: 25
eduarcol Va por buen camino
A ver, apoyandome en la idea de GluGlu resolvi el problema, aqui esta el codigo para el que le interese, basicamente lo que hace es qe toma la ultima aparicion del WHERE y divide el string en dos, luego inserta el filtro y lo vuelve a unir. Pronto lo subire a mi subdominio para el que lo necesite

Código Delphi [-]
//si el control activo es caja de texto Genera el filtro en la consulta
         //Divide la sentencia SQL
         sq.DisableControls;

         sq.Active := False;

         //Reestablece la sentencia original
         sq.SQL.Text := cSqlOriginal;

         //Inicializa las variables
         Aux_SelectSQL1 := '';
         Aux_SelectSQL2 := UpperCase(sq.SQL.Text);

         //Elimina los saltos de linea y saca como resultado Aux_SelectSQL1
         for j := 1 to Length(Aux_SelectSQL2) do begin
           if Aux_SelectSQL2[j] = #13 then
              Aux_SelectSQL1 := Aux_SelectSQL1 + ' '
           else
             if Aux_SelectSQL2[j] <> #10 then
               Aux_SelectSQL1 := Aux_SelectSQL1 + Aux_SelectSQL2[j];
         end;

         //Toma la aparicion del ultimo where
         Aux_Pos := 1;
         while PosEx(' WHERE ', Aux_SelectSQL1, Aux_Pos) <> 0 do begin
           Aux_Pos := PosEx(' WHERE ', Aux_SelectSQL1, Aux_Pos) + 1;
         end;

         //Divide la sentencia antes del where y despues del where
         Dec(Aux_Pos);
         if Aux_Pos = 0 then
         begin
            Aux_Pos := Length(Aux_SelectSQL1);
            Aux_SelectSQL1 := Aux_SelectSQL1 + ' WHERE ';
            lAgregar := False;
         end
         else
            lAgregar := True;

         cInicio  := Copy(Aux_SelectSQL1, 1, Aux_Pos + 7);
         cFinal   := Copy(Aux_SelectSQL1, Aux_Pos + 7, Length(Aux_SelectSQL1));



         //Arma el filtro dependiendo la seleccion
         if rgTipo.ItemIndex = 0 then //Comienza
            cFiltro := ' (' + rgFiltro.Items.Strings[rgFiltro.ItemIndex] + ' like ' + QuotedStr(txBuscar.Text + '%') + ')'
         else if rgTipo.ItemIndex = 1 then //Contiene
            cFiltro := ' (' + rgFiltro.Items.Strings[rgFiltro.ItemIndex] + ' like ' + QuotedStr('%' + txBuscar.Text + '%') + ')'
         else if rgTipo.ItemIndex = 2 then //Termina
            cFiltro := ' (' + rgFiltro.Items.Strings[rgFiltro.ItemIndex] + ' like ' + QuotedStr('%' + txBuscar.Text) + ')'
         else if rgTipo.ItemIndex = 3 then //Exacta
            cFiltro := ' (' + rgFiltro.Items.Strings[rgFiltro.ItemIndex] + ' = ' + QuotedStr(txBuscar.Text) + ')';

         //Determina si agrega el AND
         if lAgregar then
            cFiltro := cFiltro  + ' AND ';

         sq.SQL.Text := cInicio + cFiltro + cFinal;
         sq.Active := True;
         sq.EnableControls;
__________________
...Yo naci en esta ribera del arauca vibr@d0r
Soy hermano de la espuma,
de la garza, de la rosa y del sol...
Viva Venezuela
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
consulta a un query en vez de a una tabla eldiegofg SQL 10 19-09-2007 12:46:39
Tabla vacia que el motor de BD reporta llena Phacko Conexión con bases de datos 1 28-02-2007 06:02:34
que es más rápido query o filtrar tabla? Manuel Varios 27 29-10-2006 16:42:41
Cómo sincronizar Query y tabla David Conexión con bases de datos 2 13-07-2006 11:18:50
Tabla externa en query llonigualker Conexión con bases de datos 3 28-04-2006 12:14:22


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


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