[Gvsig_usuarios] Consulta SQL anidada a tabla alphanumérica de SHP

Alberto Calzada albertocalsa en gmail.com
Mar Ago 7 11:37:13 CEST 2012


Hola a todos de nuevo,

Estoy desarrollando una extensión para gvSIG y me he vuelto a encasillar en
un problemilla que no sé si os habrá sucedido ya a alguno. Estoy intentando
crear una consulta SQL para que me devuelva una sola fila (la que busco
para añadir los resultados de la ejecución de mi extensión).

El caso es que tengo un problema de precisión de los datos (que tanto de
entrada como de salida pueden tener cualquier valor y cualquier formato).
Por ese motivo no puedo crear la consulta de forma sencilla con valores
exactos tal que así:

select * from myTable where area = "myVariableArea" and perimeter =
"myVariablePerimeter" and etc etc

Lo de area y perimeter es un ejemplo. Yo puedo tener cualquier otro tipo de
dato entero o decimal, con cualquier número de decimales...

Por lo tanto, he decidido atacar el problema buscando "la fila más parecida
a la que busco". Por lo tanto estoy tratando de definir una consulta de
esta forma:

select * from myTable as t1 where ( select min(abs( t1.PERIMETER -
"myVariablePerimeter" + t1.AREA - "myVariableArea" + etc...

Mando este e-mail a las dos listas porque he probado a definir este tipo de
consultas primero con la interfaz gráfica de gvSIG, con la herramienta
"Filtro" de la tabla, pero me salta uno de esos bugs de cuando la consulta
no está bien definida. (Que podría ser eso porque llevo bastantes años sin
tocar SQL...). Si alguno sabe más del tema y ve algún fallo en mi consulta
estaría agradecido si me lo pudiera aclarar.

Y también lo mando a la de desarrolladores porque no tengo claro que pueda
definir consultas SQL anidadas sobre mi layer.getRecordset() y quizás
alguno de los desarrolladores supiera algo al respecto.

El código fuente que utilizo es algo así:

String sqlQuery = "select * from '"+lyr.getRecordset().getName()+"' ";
 sqlQuery += "where "+
this.generateQueryFromSample(dsl.getInputCombination(i),
lyr.getRecordset().getName());
System.out.println(sqlQuery);
lyr.setActive(true);
DataSource ds =
lyr.getRecordset().getDataSourceFactory().executeSQL(sqlQuery,
DataSourceFactory.AUTOMATIC_OPENING);
ds.start();

ShpSchemaManager schemaManager = new
ShpSchemaManager(docFile.getAbsolutePath());
schemaManager.createSchema(outputLyrDef);
 IFeatureIterator it = lyr.getSource().getFeatureIterator(sqlQuery,
lyr.getProjection());

for(int counter = 0; counter < ds.getRowCount() && it.hasNext(); counter++){
 IFeature geom = (IFeature) it.next();
LinkedList<Value> values = new LinkedList<Value>();

//Adding antecedents
Value v[] = lyr.getRecordset().getRow(counter).clone();
for(int j=0; j< fieldsExported.size(); j++){
values.add(v[fieldsExported.get(j)]);
}
//AddingConsequent
values.add(v[consequentField]);
values.add(ValueFactory.createValueByType("20.2", Types.DOUBLE, 8, 4));
geom.setAttributes(values.toArray(new Value[0]));
 DefaultRowEdited edRow = new DefaultRowEdited(geom,
DefaultRowEdited.STATUS_ADDED, counter);
edRow.setAttributes(values.toArray(new Value[0]));
writeSHP.process(edRow);
}
writeSHP.postProcess();

Donde la función "generateQueryFromSample" es la siguiente (para formar la
subconsulta anidada):

private String generateQueryFromSample(Sample s, String tableName){
String query = " ( select min(abs( ";
for(int i=0;i<dsl.getHeaderTreeNodes().size();i++){
if(dsl.getHeaderTreeNodes().get(i).getReferentialSetOfValues().isSpatial()){
Input input = s.getInputByTreeNode(dsl.getHeaderTreeNodes().get(i));
if(input instanceof InputNumerical){
query +=
dsl.getHeaderTreeNodes().get(i).getReferentialSetOfValues().getSpaAttName()
+ " - " + input.print();
 if(i<dsl.getHeaderTreeNodes().size() -1)
query += " + ";
}
}
}
return query + ")) FROM "+tableName+");";
}

Y bueno, por si os sirviera de algo para diagnosticar alguno de los muchos
fallos que tengo por aquí, dejo también el stack del error en tiempo de
ejecución que me salta cuando intento procesar la consulta:

getDbfIdForCharset windows-1252 dbfId = 0
*select * from 'gdbms6b0a742e_139006f52eb__8000' where  ( select min(abs(
PERIMET*
*ER - 135.43919372558594 + AREA - 1071.75146484375 + h_p - 0.0)) FROM
gdbms6b0a74*
*2e_139006f52eb__8000);*
Exception in thread "Thread-2624"
com.hardcode.gdbms.parser.SQLEngine$LookaheadS
uccess
        at com.hardcode.gdbms.parser.SQLEngine.<init>(SQLEngine.java:3462)
        at
com.hardcode.gdbms.engine.data.DataSourceFactory.executeSQL(DataSourc
eFactory.java:1609)
        at
model.spatial.GISOutputExporterVectorLayer.addData(GISOutputExporterV
ectorLayer.java:224)
        at
model.core.Execution.executeRimerCrossValidation(Execution.java:223)
        at model.core.Execution.access$2(Execution.java:210)
        at model.core.Execution$ActualTask.<init>(Execution.java:256)
        at model.core.Execution$2.construct(Execution.java:96)
        at model.threadExec.SwingWorker$2.run(SwingWorker.java:60)
        at java.lang.Thread.run(Unknown Source)

En negrita es un system.out.println de la consulta que hago.
Decir que cuando hago una consulta simple sin la claúsula "WHERE" sí que me
devuelve un DataSource con todos los registros de mi tabla, por lo que la
tabla, y creo que los campos, sí que son correctos.

Espero que alguien me pueda echar un cable,

Muchísimas gracias de antemano,

Un saludo,

Alberto


-- 
*--
*

*Mr Alberto Calzada
Full-time PhD Candidate*

*Room 16J25 *

*School of Computing and Mathematics
Faculty of Computing and Engineering*

*University of Ulster at Jordanstown Campus
Northern Ireland, UK
Email: Calzada-A en email.ulster.ac.uk*

*Tel:  +44 28 90361114 *
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: http://listserv.gva.es/pipermail/gvsig_usuarios/attachments/20120807/7fba953b/attachment.htm 


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