[Gvsig_desarrolladores] consulta SQL involucrando varias tablas

marcos boullón magán marcosboullon en gmail.com
Vie Ago 25 20:21:18 CEST 2006


Hola,

No sé si a estas alturas ya estará corregido, pero he tardado más de
dos horas en encontrar este error y prefiero avisar a otros incautos.

En el código que me han enviado (PostGisDriver.zip) en este hilo y que
permitía que se pudieran cargar capas (desde una BBDD PostGIS)
filtrando mediante la cláusula WHERE (código que se incorporará a la
versión 1.0 no-alpha), hay un pequeño inconveniente: se comprueba si
el usuario incluye una cláusula WHERE con "if
(getWhereClause().indexOf("WHERE") != -1)", pero ¡el WHERE sólo se
comprueba en mayúsculas!

Así que si quieres cargar sólo algunos datos de una tabla utilizando
WHERE, o te acuerdas de ponerlo en mayúsculas 'lyrDef.setWhereClause("
WHERE valor<100 ")' o conseguirás bonitos errores como...

java.lang.IndexOutOfBoundsException: bitIndex < 0: -1
 at java.util.BitSet.get(BitSet.java:459)
 at com.iver.cit.gvsig.fmap.operations.strategies.DBStrategy.draw(Unknown
Source)
 at com.iver.cit.gvsig.fmap.layers.FLyrVect.draw(Unknown Source)
 at com.iver.cit.gvsig.fmap.layers.FLayers.draw(Unknown Source)
 at com.iver.cit.gvsig.fmap.FMap.draw(Unknown Source)
 at com.iver.cit.gvsig.fmap.MapControl$PaintingRequest.paint(Unknown Source)
 at com.iver.cit.gvsig.fmap.MapControl$Drawer2$Worker.run(Unknown Source)
 at java.lang.Thread.run(Thread.java:534)

... ¡que en ningún momento hacen referencia a PostGisDriver.java!

Gracias por todo,

Marcos

2006/8/22, marcos boullón magán <marcosboullon en gmail.com>:
> Hola,
>
> Y me vuelvo a responder una vez más. Al final he encontrado mi
> problema, y era simplemente que cuando creo una vista o una tabla
> nueva necesito modificar la tabla de PostGIS "geometry_columns"
> manualmente; sino, al intentar cargar la capa obtengo ese error tan
> descriptivo de "Result set not positioned properly".
>
> En resumen, que no hay problema en crear tablas nuevas o vistas desde
> gvSIG (y así procesar datos de varias tablas simultáneamente), y luego
> cargarlas como capas en el GIS. Se debe utilizar:
>
> s.execute("create view tmp001 as select ... from ...") ó
> s.execute("select ... into table tmp001 from ...")
>
> y luego introducir una fila más en "geometry_columns" emulando la
> función "AddGeomtryColumns()" (no se puede usar esa función porque la
> tabla/vista ya tiene datos después de llamar a "execute()").
>
> Los inconvenientes del método son que es un proceso en varios pasos, y
> que necesitamos acceso de escritura (a la BBDD y a la tabla
> "geometry_columns").
>
> Suerte a todos,
>
> M.
>
> 2006/8/21, marcos boullón magán <marcosboullon en gmail.com>:
> > Hola,
> >
> > Me respondo a mí mismo (el correo anterior lo contesté en privado por
> > error; aquí lo amplío y envío a la lista de desarrolladores).
> >
> > El problema de acceder a varias tablas simultáneamente parece que
> > puede ser resuelto creando una vista temporal con...
> >
> > Connection conn0 = DriverManager.getConnection(dbURL, user, pwd);
> > Statement s0 = conn0.createStatement();
> > boolean r0 = s0.execute("create view tmp001 as select ... ");
> >
> > El problema que me aparecía (y que impedía que se creara la vista) era
> > debido a utilizar "conn0.setAutoCommit(false);". Comentada esa línea,
> > me crea la vista y a continuación ya puedo cargarla en una capa.
> >
> > Todavía no es el sistema perfecto (necesito permisos de escritura
> > sobre la base de datos), y me queda solucionar algún error al cargarla
> > ("Result set not positioned properly, perhaps you need to call
> > next()."), y usarla ("java.lang.NullPointerException") pero es mejor
> > que nada. Da la sensación de que estos errores siempre saltan cuando
> > se consultan vistas... ¿Alguien me lo puede confirmar? ¿Alguien puede
> > cargar una vista en una capa sin ver errores? ¿Voy a tener que crear
> > tablas temporales en vez de vistas?
> >
> > Gracias,
> >
> > M.
> >
> > ERROR [AWT-EventQueue-1] (?:?) - org.postgresql.util.PSQLException:
> > Result set not positioned properly, perhaps you need to call next().
> > org.postgresql.util.PSQLException: Result set not positioned properly,
> > perhaps you need to call next().
> >         at org.postgresql.jdbc1.AbstractJdbc1ResultSet.checkResultSet(AbstractJdbc1ResultSet.java:818)
> >         at org.postgresql.jdbc1.AbstractJdbc1ResultSet.getString(AbstractJdbc1ResultSet.java:195)
> >         at org.postgresql.jdbc1.AbstractJdbc1ResultSet.getFixedString(AbstractJdbc1ResultSet.java:787)
> >         at org.postgresql.jdbc1.AbstractJdbc1ResultSet.getInt(AbstractJdbc1ResultSet.java:282)
> >         at org.postgresql.jdbc1.AbstractJdbc1ResultSet.getInt(AbstractJdbc1ResultSet.java:496)
> >         at com.iver.cit.gvsig.fmap.drivers.jdbc.postgis.PostGisDriver.getTableEPSG(Unknown
> > Source)
> >         at com.iver.cit.gvsig.fmap.drivers.jdbc.postgis.PostGisDriver.setData(Unknown
> > Source)
> >         at es.usc.laborate.gvsig.queryespazos.gui.QueryEspazosSelectionPanel.getQueryLayerloadView(QueryEspazosSelectionPanel.java:448)
> > [...]
> >
> > java.lang.NullPointerException
> >         at com.iver.cit.gvsig.fmap.operations.strategies.DBStrategy.queryByRect(Unknown
> > Source)
> >         at com.iver.cit.gvsig.fmap.operations.strategies.DefaultStrategy.queryByRect(Unknown
> > Source)
> >         at com.iver.cit.gvsig.fmap.layers.FLyrVect.queryByRect(Unknown Source)
> >         at com.iver.cit.gvsig.fmap.tools.RectangleSelectionListener.rectangle(Unknown
> > Source)
> >         at com.iver.cit.gvsig.gui.toolListeners.RectangleSelectListener.rectangle(Unknown
> > Source)
> >         at com.iver.cit.gvsig.fmap.tools.Behavior.RectangleBehavior.mouseReleased(Unknown
> > Source)
> >         at com.iver.cit.gvsig.fmap.tools.CompoundBehavior.mouseReleased(Unknown
> > Source)
> >         at com.iver.cit.gvsig.fmap.MapControl$MapToolListener.mouseReleased(Unknown
> > Source)
> >         at java.awt.Component.processMouseEvent(Component.java:5100)
> > [...]
> >
> > 2006/8/21, marcos boullón magán <marcosboullon en gmail.com>:
> > > Gracias Francisco,
> > >
> > > Lo he estado probando esta mañana y me funciona perfectamente. Gracias
> > > por preocuparte.
> > >
> > > Sin embargo aún tengo el problema de consultar varias tablas
> > > simultáneamente y extraer datos de todas ellas. He estado probando a
> > > crear una vista temporal donde introducir los datos de las tablas que
> > > me interesan y cargar luego esa vista en lugar de las tablas
> > > originales. Es decir, viendo que puedo enviar una secuencia SQL con
> > > los métodos executeQuery() o execute(), he probado algo como....
> > >
> > > Connection conn = DriverManager.getConnection(dbURL, user, pwd);
> > > Statement s = conn.createStatement();
> > > ResultSet r = s.executeQuery("create view tmp001 as select tabla1.id,
> > > tabla1.geometria for tabla1,tabla2 where
> > > tabla1.geometria&&tabla2.geometria and tabla1.valor<tabla2.valor");
> > > r.next();
> > >
> > > ... y después podría ya cargar la vista "tmp001" como ya hacía antes
> > > (ahora filtrando con cláusulas where). Sin embargo, obtengo un error
> > > "no results returned by the query"...
> > >
> > > org.postgresql.util.PSQLException: No results were returned by the query.
> > >         at org.postgresql.jdbc1.AbstractJdbc1Statement.executeQuery(AbstractJdbc1Statement.java:238)
> > >         at org.postgresql.jdbc1.AbstractJdbc1Statement.executeQuery(AbstractJdbc1Statement.java:221)
> > >         at es.usc.laborate.gvsig.queryespazos.gui.QueryEspazosSelectionPanel.getQueryLayer(QueryEspazosSelectionPanel.java:372)
> > >         at
> > > ...
> > >
> > > ¿Se os ocurre cómo puedo enviar el comando a la base de datos
> > > PostgreSQL para crear esa vista temporal? ¿Cómo puedo evitar ese
> > > error? Mis conocimientos de Java y del JDBC son bastante pobres...
> > >
> > > Gracias por todo,
> > >
> > > Marcos
> > >
> > > PD: He encontrado un listado de ese método en el CVS del proyecto
> > > PostgreSQL, en http://gborg.postgresql.org/cgi-bin/cvsweb.cgi/pgjdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java?rev=1.55;content-type=text%2Fplain;cvsroot=pgjdbc;hideattic=0
> > > por si sirve de ayuda.
> > >
> > > El 21/08/06, Francisco José<fpenarru en iver.es> escribió:
> > > > Hola Marcos.
> > > >
> > > > Tal y como quedamos, te envío el nuevo driver de PostGIS modificado.
> > > > Tendrás que hacer un "diff" de este fichero con el tuyo y coger 3
> > > > trocitos en los que ha cambiado la forma de trabajar con
> > > > "compoundWhere". Si has más cambios, son debidos a otras cosas de la
> > > > nueva versión, así que no los copies.
> > > >
> > > > En la siguiente versión, hemos añadido en el diálogo un cuadro de texto
> > > > para que el usuario especifique la cláusula where con la que quiere
> > > > trabajar. Así podrás probar bien esta parte.
> > > >
> > > > Respecto a lo que apuntas de unir dos tablas, ya nos lo había solicitado
> > > > Erwan Bocher (saludos) hace un tiempo. Ahora mismo con este driver no se
> > > > puede, pero es algo que nos pareció una muy buena idea, y es una de las
> > > > "muchas - demasiadas" cosas que tenemos pendiente.
> > > >
> > > > Por el momento, y para practicar con el código, Erwan se hizo un driver
> > > > que le permitía trabajar con esas consultas (eso sí, cargando las
> > > > entidades en memoria).
> > > >
> > > > Resumiendo, que buena idea, pero que hasta que no salga la versión
> > > > estable 1.0, no creo que nos pongamos con ello. Lo mismo que tenemos
> > > > pendiente poner una consola para usuarios avanzados que permita lanzar
> > > > cualquier tipo de consulta sobre la base de datos (para crear buffers,
> > > > intersecciones, etc directamente con PostGIS).
> > > >
> > > > Saludos, y como dicen los "yanquis": keep going!!.
> > > >
> > > > marcos boullón magán escribió:
> > > > > Hola,
> > > > >
> > > > > Una última consulta sobre el tema de gvSIG y PostGIS.
> > > > >
> > > > > Yo abro una conexión a mi base de datos mediante el uso del método
> > > > > "LayerFactory.createDBLayer(driver, "título", proj)", donde "driver"
> > > > > tiene la información de la consulta SQL almacenada en un objeto
> > > > > DBLayerDefinition. En ese objeto es donde he definido el nombre de la
> > > > > tabla, columnas que me interesan, geometría, fid... que gvSIG se
> > > > > encarga de procesar para obtener una llamada SQL estándar: "SELECT
> > > > > asbinary(geometria,'xdr'),id,valor FROM tabla ORDER by id".
> > > > >
> > > > > Mi pregunta es, ¿hay alguna forma de conseguir hacer una consulta a la
> > > > > base de datos que involucre a varias tablas? Me gustaría cómo realizar
> > > > > una llamada equivalente al SQL "SELECT
> > > > > asbinary(tabla1.geometria,'xdr'), tabla1.id, tabla1.valor,
> > > > > tabla2.valor FROM tabla1, tabla2 WHERE tabla1.valor=tabla2.valor ORDER
> > > > > by tabla1.id" (aunque la operación es algo idiota, creo que se
> > > > > entiende el problema, ¿no? Se trata de tener atributos de varias
> > > > > tablas).
> > > > >
> > > > > Gracias por adelantado,
> > > > >
> > > > > Marcos
> > > > >
> > > > > PD: Realmente lamento daros tanto la lata.
> > > > >
> > > >
> > > >
> > > > --
> > > > Francisco José Peñarrubia
> > > > Equipo gvSIG
> > > >
> > > > IVER T.I. S.A.
> > > > c/Salamanca 50
> > > > 46005 Valencia
> > > > Spain
> > > >
> > > >
> > > >
> > > >
> > >
> > > --
> > > -- marcos boullón magán
> > >
> >
> > --
> > -- marcos boullón magán
> >
>
> --
> -- marcos boullón magán
>

-- 
-- marcos boullón magán



Más información sobre la lista de distribución gvSIG_desarrolladores