2011-08-28 21 views
36

imaginar que tienen una consulta comoconjunto de resultados JDBC obtener columnas con alias de tabla

SELECT * from table1 a, table2 b where (WHATEVER) 

Tal vez ambas tablas tienen el mismo nombre de la columna. Así que pensé que sería bueno acceder a los datos a través de

resultSet.getString("a.columnName"); 
resultSet.getString("b.columnName"); 

Pero esto me falla y no consigo nada. Leí la API, pero realmente no hablan sobre este caso. ¿Es dependiente de tal característica del vendedor?

Respuesta

39

JDBC simplemente indicar las columnas por lo que se especifica en la consulta - que no sabe nada de los nombres de tabla etc.

Usted tiene dos opciones:

Opción 1: Nombre las columnas de manera diferente en la consulta, es decir,

SELECT 
    a.columnName as columnNameA, 
    b.columnName as columnNameB, 
    ... 
from table1 a, table2 b where (WHATEVER) 

continuación en el código java se refieren a los alias de columna:

resultSet.getString("columnNameA"); 
resultSet.getString("columnNameB"); 


Opción 2: Consulte la columna posición en su llamada a la API JDBC:

resultSet.getString(1); 
resultSet.getString(2); 

Tenga en cuenta que la API JDBC utiliza basados ​​en una índices - es decir, que cuentan a partir 1 (no de 0 como índices de Java), a fin de utilizar 1 para la primera columna, 2 para la segunda columna, etc


Yo recomendaría la opción 1, porque es más seguro para hacer referencia a las columnas con nombre: Alguien puede cambiar el orden de las columnas de la consulta y se rompería en silencio su código (que estaría accediendo a la columna equivocada, pero no sabría), pero si cambian los nombres de las columnas, al menos obtendrá una excepción de "no dicha columna" en el tiempo de ejecución.

+0

ve bien que voy a tener que olvidar el buen * y el nombre de todo y utilizar una asignación adicional. –

8

Use alias de columna como SELECT A.ID 'A_ID', B.ID 'B_ID' FROM TABLE1 AS A, TABLE2 AS B... y especificar todas las columnas que va a recuperar (es una buena práctica).

0

Puede utilizar alias en el nivel de SQL. Entonces se recuperan datos de índices. (Sin embargo, este enfoque hará que el mantenimiento de una verdadera pesadilla)

SELECT a.column, b.column FROM table1 a, table2 b 

String value = rs.getString(1); 
0

Una idea que tenía es utilizar el getTableName(iCol) para agarrar los nombres de tabla para las columnas duplicately con nombres, luego envolver un hash de sus propias claves (con la nombre de la tabla de prefijo) que apuntaría a que el índice de columna correcto, y hacer referencia a la columna valores de esa manera. Esto requeriría un ciclo inicial a través de los metadatos al comienzo de la configuración. El único problema que veo con esto es que también está aliasing los nombres de la tabla. Todavía tengo que encontrar una manera de conseguir los alias de nombres de tabla de JDBC sin lograr por sí mismo cuando se genera la instrucción SQL. Esta solución dependería de lo que le pagaría la ganancia sintáctica.

+0

@Bohemian: puede usar la función ResultSetMetaData :: getTableName (int) para obtener el nombre de tabla. Sin embargo, no estoy seguro si el resultado depende de la implementación de jdbc. https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSetMetaData.html#getTableName(int) – inyourcorner

0

Ok, parece que no hay método como resultSet.getString("a.columnName"); y hay que asignar un alias a sus columnas a nivel SQL, pero, puesto que hay un método getTableName(iCol) espero chicos de java.sql.ResultSet añadir esta característica.

9

ResultSetMetaData.getColumnLabel() es lo que necesita

(editar) ejemplo muestra, según lo declarado por bharal en el comentario

SELECT * from table1 a, table2 b where (WHATEVER) 

ResultSetMetaData rsmd = rset.getMetaData(); 
rsmd.getColumnLabel(1); 
+1

¿por qué y cómo y qué es un ejemplo de esto funcionando? – bharal

+0

allí usted editó la respuesta mediante un fragmento de código de muestra – Mateen

2

Si está utilizando MySQL sólo tiene que añadir

&useOldAliasMetadataBehavior=true 

a su connectionString.

Después se puede utilizar este pequeño ayudante:

import java.sql.ResultSet; 
import java.sql.ResultSetMetaData; 
import java.sql.SQLException; 
import java.util.HashMap; 
import java.util.Map; 

public class ResultSetHelper { 

    private final Map<String, Integer> columnMap; 

    public ResultSetHelper(ResultSet rs) throws SQLException { 
     this.columnMap = new HashMap<>(); 
     ResultSetMetaData md = rs.getMetaData(); 
     int columnCount = md.getColumnCount(); 
     for (int index = 1; index <= columnCount; index++) { 
      String columnName = md.getColumnLabel(index); 
      if (!columnMap.containsKey(columnName)) { 
       columnMap.put(columnName, index); 
      } 

      String tableAlias = md.getTableName(index); 
      if (tableAlias != null && !tableAlias.trim().isEmpty()) { 
       columnMap.put(tableAlias + "." + columnName, index); 
      } 
     } 
    } 

    public Integer getColumnIndex(String columnName) { 
     return columnMap.get(columnName); 
    } 

    public Integer getColumnIndex(String tableAlias, String columnName) { 
     return columnMap.get(tableAlias + "." + columnName); 
    } 

} 
Cuestiones relacionadas