![]() |
Consulta con dos bbdd
Hola buenas,
soy nuevo en este foro, la verdad que me habéis resuelto muchos problemas que he tenido así que gracias de antemano :D. Ando un poco desesperado porque no consigo dar con la solución al problema que se me ha presentado. Por más que busco no encuentro solución. Espero no haberme equivocado en el lugar de plantearlo. Os expongo los datos de mi problema: Trabajo con Delphi XE 6 y tengo dos bases de datos gestionados mediante Interbase, son distintas, es decir, contienen tablas distintas. Necesito hacer una consulta que una dos tablas de las dos bases de datos(una tabla en cada base de datos), por un mismo campo que tienen en común. Os lo expongo con el ejemplo: BBDD1 TABLA PROYECTMANAGER CAMPOS NUMEROPM VENTAS PROYECTOS<-- Este es el campo a igualar ... BBDD2 TABLA FACTURAS CAMPOS DOCNUM DOCBASEIMP PROYECTOS <-- Este es el campo a igualar ... Bien, he intentado hacer dos IBQuerys con sus respectivos SELECTS en la propiedad SQL. IBQuery1 lo asigno a DataSetProvider1 mediante su propiedad DataSet y IBQuery2 a DataSetProvider2. Aquí es donde viene mi problema, intentar juntar esas dos consultas en un mismo ClientDataSet o en dos ClientDataSet y que se junten en un mismo DBGrid. He conseguido asignar un DataSetProvider a cada ClientDataSet mediante su campo ProviderName, luego hacer doble click, Ctrl+A, insertar los campos de la consulta y de ahi asignarlo a dos DBGrids distintos. Pero no consigo que se junten las dos querys. Para aclararlo un poco más, lo que realmente yo quiero es hacer una consulta que me diga todas los FACTURAS que pertenecen a un PROYECTMANAGER. Por eso pensé en dividirlo en dos consultas: 1ºConsulta: que muestre todos los proyectos que tiene un ProyectManager en concreto 2ºConsulta: con esos proyectos de la consulta anterior sacar todas las facturas. Pero no consigo juntarlos en el ClientDataSet. ¿Podríais echarme una mano? Muchísimas gracias de verdad! |
Interbase no es exactamente igual que Firebird, lo comento porque con Firebird puedes consultar una base de datos externa.
De todas formas, de la forma en que lo haces también es perfectamente posible. Debes hacerlas totalmente independiente, cada una con su conexión, transacción, dataset, etc. y luego puedes recorrer ambas e ir añadiendo los registros a un clientdataset, por ejemplo. |
Hola Casimiro,
muchas gracias por contestar, se que a lo mejor es una tontería lo que me queda pero no lo consigo, podrías detallar tu respuesta un poco más.:) Muchas gracias de nuevo! |
Hola, me refería a hacer lo que tú mismo has comentado:
Cita:
Cita:
|
Perdona a lo mejor no me he expresado bien:(, yo he conseguido que por separado se muestren, es decir, tengo esto:
IBDataBase1>>IBTransaction1>>IBQuery1>>DataSource1>>DataSetProvider1>>ClientDataSet1 y de ahi a un Grid. IBDataBase2>>IBTransaction2>>IBQuery2>>DataSource2>>DataSetProvider2>>ClientDataSet2. Con esto no tengo problema, lo que no se hacer es(desarrollarlo) o bien que los dos ClientDataSet se unan en un tercero y que se cruce la información de todos los Proyectos de un Proyect Manager o que lo hagan antes y solo se utilice un ClientDataSet. Mi problema es que no se terminar de juntarlos :(. P.D. Lo he hecho todo en Diseño. |
Por eso te digo:
Cita:
|
Lo que me ocurre es que no se seguir. En tiempo de diseño lo tengo todo planteado(como he comentado lo tengo todo atado bien por separado) justo antes de juntar las dos consultas, es decir, no se recorrer los resultados(PROYECTOS) de la tabla PROYECTMANAGER, y que sirvan de parámetro para que solo se muestren en la tabla FACTURAS esos proyectos que ha recogido la consulta primera.
No se como recoger el resultado en el ClientDataSet y de ahi al Grid. Solo tengo la parte en tiempo de diseño. Todo mediante propiedades de los objetos. En código solo tengo: procedure TPrueba1Form.Button1Click(Sender: TObject); begin IBQuery1.Close; IBQuery1.Open; IBQuery2.Close; IBQuery2.Open; end; Espero que sirva de aclaración :). |
A ver, no entiendo el problema, tendrás que ser más específico.
Si tienes dos dataset (ibquery), debes recorrerlos e ir insertando los datos en otro query/dateset/clientdatset (lo que prefieras) y olvídate de dbgrid, ahí no tienes que hacer nada. Algo similar a: Ya están los registros en ibqueryconjunto, añades un datasource que apunte al mismo y al dbgrid también. Y recuerda poner los tags al código fuente, ejemplo: ![]() Gracias :) |
Casimiro muchas gracias,
creo que ahí está la clave voy a probarlo, un par de preguntas y disculpa mi ignorancia, en:
¿que debo poner en ibquery1.xxxx? Y por último, estos dos bucles recorren todos los registros de las dos tablas y los añaden al datasetconnjunto, si no me equivoco, pero ¿como hago para que la segunda consulta solo añada los registros de que coincidan con el campo común de la primera consulta? Es decir,si yo tengo: 1ºConsulta
2ºConsulta <-- Y que aquí saque las facturas de los proyectos listados en la consulta anterior :P. Muchas gracias por tu ayuda Casimiro. Esto se me está atascando y tranquiliza mucho que alguien esté dispuesto a ayudarte. Disculpa las molestias. |
Cita:
Quiero decir que si buscas el proyecto=5, ya habrás hecho el "where proyecto=5" en ambas consultas, por lo que no tendrás que hacer nada más, te has traido los datos válidos de ambas BD. |
Lo que yo quiero es que pasando por un edittext el código del Proyect Manager, me liste todos los Proyectos y sus facturas correspondientes.
El problema es que en la segunda base de datos no existe ningún campo que sea ProyectManager, por eso el "where CODIGOPM=6" (ya que yo supuse que necesitaría dos consultas) rescatará todos los proyectos de ese Proyect Manager y de todos esos proyectos quiero saber las facturas correspondientes. Te muestro en un esquema la relación que quiero: Primera BBDD Segunda BBDD TABLA PROYECTMANAGER TABLA PROYECTMANAGER CODIGOPM NUMEROFAC NOMBRPM IMPORTE PROYECTOS<------------------------------------------->PROYECTOS … |
Lo que yo quiero es que pasando por un edittext el código del Proyect Manager, me liste todos los Proyectos y sus facturas correspondientes.
El problema es que en la segunda base de datos no existe ningún campo que sea ProyectManager, por eso el "where CODIGOPM=6" (por eso supuse que necesitaría dos consultas) rescatará todos los proyectos de ese Proyect Manager y de todos esos proyectos quiero saber las facturas correspondientes. Te muestro en un esquema la relación que quiero:
Es decir la consulta dos debería ser una consulta anidada de la otra :). |
Pero se supone que el campo 'proyectos' de la segunda BD tendrá el código del campo 'proyectos' de la primera BD, ¿no?
Por cierto, ¿por qué están en bases de datos separadas? |
Es el mismo campo sí, por decisión de los anteriores programadores se estableció así la estructura de las bbdds, yo tampoco le ví mucho sentido. Pero me es imposible cambiar la estructura de la base de datos, si estuvieran en la misma base de datos, sería solo hacer un SELECT, un join de las claves y el Where = 'codigo del Edittext'.
Pero necesito hacerlo desde Delphi. |
Realmente yo no necesito mostrar ni guardar los datos de la primera consulta, pero si que tienen que servir de filtro para la segunda, es decir, que coja los proyectos en la primera tabla, y que la segunda haga la consulta de todos esos proyectos.
|
Cita:
El usuario elige un proyecto, ejemplo, el 6 Buscas en la BD1 el proyecto con el número 6. Buscas en la BD2 los registros con proyecto número 6. Se supone que tienes un query con el registro del proyecto 6 de la BD1. Se supone que tienes un query con los registros del proyecto 6 de la BD2. ¿Y ahora qué quieres hacer? |
No Casimiro el usuario elige un ProyectManager, ejemplo, el 6, hacemos la búsqueda de los proyectos en la BBDD1 de ese ProyectManager y este tiene 3 proyectos:
001 002 003 A continuación quiero buscar cada una de las facturas de esos proyectos en la BBDD2: 001-->1,2,3 002-->4,5,6 003-->7,8,9 |
Lo siento, no entiendo cómo están estructuradas y relacionadas esas tablas y bases de datos.
Pon un ejemplo con los datos que has escrito antes. BD, tabla, campos, valores |
Las bases de datos no están relacionadas de ahí mi problema,
te expongo lo que he intentado hacer con tu ayuda a ver si así ves mejor el problema:
Previamente cree en el ClientDataSet los Fields PROYECTO y FACTURA. De esta manera me lista los proyectos perfectamente pero las facturas me salen vacías, de esta forma: PROYECTO FACTURA 001 002 003 004 Es un avance pero se me escapa algo. No se si esta información te sirve de algo. :) BBDD1 Tabla PROYECTMANAGER CODIGOPM-->6 PROYECTOS -->1,2,3 NOMBRE--> Carlos BBDD2 Tabla FACTURAS PROYECTO-->1 NUMEROFAC-->001,002,003 IMPORTE -->100€,200€,300€ PROYECTO-->2 NUMEROFAC-->004,005,006 IMPORTE -->1500€,2500€,3500€ PROYECTO-->3 NUMEROFAC-->007,008,009 IMPORTE -->50000€,60000€,30000€ |
Vale Casimiro, casi lo tengo:
El problema que solo me muestra el primer proyecto de ese ProyectManager esto me muestra con respecto al ejemplo anterior me muestra: PROYECTO-->1 NUMEROFAC-->001,002,003 IMPORTE -->100€,200€,300€ |
Cita:
¿A qué lumbreras se le ocurrió esa chapuza inmensa, además dividido en 2 bases de datos? Creo que necesitas hacer una reestructuración del sistema. Eso es una chapuza tremenda. |
Perdona las comas las he puesto yo, pero ya tengo la solución(aunque tengo un problema):
Mi problema ahora es que es extremadamente lento(10 segundos).¿Se te ocurre algo? Y estoy contigo, es una enorme chapuza, y porque no has visto la base de datos, si no te daría algo. De todas formas muchas gracias de nuevo! :D |
Cita:
Entonces la estructura de las bases de datos y lo que se guarda en los campos esos, ¿cómo es?, ¿no es como estás informando?, ¿entonces de qué estamos hablando? :confused: El sistema que empleas es lento porque recorres todo ibquery2 por cada ibquery1. |
Perdona Casimiro,
ha sido que he mostrado yo los datos mal los datos no están separados por comas, en lugar de separarlos por espacios para mostrarte los resultados. Lo he hecho con "," para separarlos pero en la base de datos no hay nada más que el dato. Por lo que he visto parece buena opción hacer un vínculo ODBC de las BBDD, unificarlas y hacer la consulta como si se tratara de una BBDD. ¿Te parece buena solución? ¿Sabes si hay información en el foro sobre esto? Ando un poco pegado con esto la verdad. Un saludo y muchas gracias de nuevo!:D |
Cita:
Veamos si he comprendido, en esos campos tienes valores separados por espacio, ejemplo: importe=100,25 325,68 489,21 ¿Eso es así? |
Perdona, lo que yo quería mostrar con las comas, eran los datos que contienen esas tablas. No ha sido la mejor forma de mostrar los datos, perdón.
Ejemplo:
|
Y la otra tabla, pon un ejemplo similar, por favor.
|
|
Pero si lo tienes hecho. De la BD1 extraes los proyectos:
Luego puedes crear un string con el resultado, mediante un bucle, algo similar a: Ahora tienes en cProyectos algo así: 1,2,3, Quitas la última coma, que sobra. Ahora montas una sql para la BD2 ibquery2.selectsql.text='select proyecto,factura,importe where proyecto in (' + cProyectos + ')' Y la ejecutas. Ya tienes los resultados en el ibquery2, que si lo enlazas mediantes un datasource a un dbgrid... ya está. |
Eyyy que buena idea :).
Lo pruebo este mediodía y te digo algo :D. Muchas gracias!! |
Buenas Casimiro,
estoy retomando el tema y tiene muy buena pinta, porque me quitaría un bucle anidado. Una pregunta ¿Como recorro el String para que se tome como parámetro la variable cProyectos en la segunda consulta? Muchas gracias!:) |
Cita:
Por ejemplo, si en cProyectos tenemos '1,2,5,14,22,' quitamos la última coma y la sentencia quedará como he puesto antes: Por lo que la variable unavariable tendría: Lo asignas al query y lo ejecutas, nada más. |
He eliminado la coma última, y he hecho lo que me has puesto, pero me salen los campos vacíos, sin embargo si en cProyectos lo igualo a un solo numero de proyecto, si que me coge los datos. Pero el string lleno de proyectos no. Es decir, solo con un numero de proyecto si que va, con varios separados por comas no.:(
¿Por qué puede ser esto? |
Cita:
|
Con este ejemplo si que funciona, ha sido una prueba que quería hacer ya que con la variable asignada a un solo proyecto si que funciona :P, ademas superrapido.
Y este sería el código que debería funcionar:
La segunda al dejar la variable con los proyectos separados por ',' no muestra resultado, sin embargo la primera va clavada, muestra los resultados de ese proyecto. |
Esto va al revés:
De todas formas, pon un breakpoint en la línea IBQuery2.Open y cuando se detenga ahí, mira el valor de IBQuery2.SQL.Text |
El valor de
Me pilla perfecto todos los proyectos, pero no los muestra :(. |
Coge la sentencia (copy/pega) y ejecútala en el flamerobin, ibexpert o en el 'manager' que uses.
|
Código:
171,18 1,196, |
Pongo otro ejemplo mas corto
y me sigue sin mostrar. y aquí no ha espacio. |
La franja horaria es GMT +2. Ahora son las 18:08:07. |
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