2012-02-12 21 views
6

Cuando uso PostgreSQL, encontré código siguiente:¿Es correcto que "ResultSet.getMetaData.getTableName (col)" del controlador jdbc de postgresql siempre devuelva una cadena vacía?

Statement stmt = conn.createStatement(); 
ResultSet rs = stmt.executeQuery("select * from t"); 

String tableName = rs.getMetaData().getTableName(1); 
System.out.println(tableName); 

Imprime una cadena vacía.

Comprobé el código fuente y encontré que el método org.postgresql.jdbc2.AbstractJdbc2ResultSetMetaData#getTableName siempre devuelve una cadena vacía.

El código fuente es:

public abstract class AbstractJdbc2ResultSetMetaData implements PGResultSetMetaData { 

    /* 
    * @param column the first column is 1, the second is 2... 
    * @return column name, or "" if not applicable 
    * @exception SQLException if a database access error occurs 
    */ 
    public String getTableName(int column) throws SQLException 
    { 
     return ""; 
    } 
} 

Se puede ver que sólo devuelve un "".

encontré una discusión sobre esto, por favor ver: http://archives.postgresql.org/pgsql-jdbc/2009-12/msg00100.php

Ellos piensan "rs.getMetaData.getTableName (col)" debería devolver el nombre de alias en no consulta el nombre de la tabla subyacente. Pero es difícil de implementar, por lo que es mejor dejarlo vacío.

También se dio un método para obtener el nombre de la tabla, utilice:

PGResultSetMetaData.getBaseTableName() 

muestra:

ResultSet rs = stmt.executeQuery("select * from x"); 
// convert it to PGResultSetMetaData 
PGResultSetMetaData meta = (PGResultSetMetaData)rs.getMetaData(); 
String tableName = meta.getBaseTableName(1); 

Ahora se puede imprimir el nombre de la tabla correcta.

No sé si la implementación de postgresql es correcta, pero devolver el nombre de tabla subyacente es mucho más útil que una cadena vacía y la mayoría de las otras bases de datos proporcionan el nombre de tabla subyacente en lugar de una cadena vacía.

Tengo un problema al usar el framework anorm de play2 con postgesql: Play2's anorm can't work on postgresql, pero eso funciona bien en otras bases de datos.

¿Cuál cree usted que es la implementación correcta del controlador jdbc de postgresql? ¿Devuelve una cadena vacía, un nombre de tabla subyacente u otra cosa?

Respuesta

3

Diría que devolver una cadena vacía es obviamente una implementación incorrecta de la interfaz, ya que el nombre de la tabla nunca podría considerarse una cadena vacía.

El problema con el que creo que están luchando es que, aunque su implementación actual es incorrecta, una vez que elijan una implementación, se quedarán con ella hasta que decidan que es aceptable romper las dependencias del comportamiento. Por lo tanto, eligen agregar un método cuyo nombre no es ambiguo y proporcionan los datos que la mayoría de los usuarios esperaban del getTableName, y dejan una implementación obviamente rota del método getTableName hasta que se llega a un consenso sobre lo que debería devolver o hasta que un parche se envía que implementa el consenso.

Mi reacción es que el método getTableName debe devolver el alias que se utiliza para esa tabla. Se podría unir una tabla consigo misma, y ​​usar el alias le permitiría identificar a cuál se estaba haciendo referencia. Es posible que se haya generado una tabla en la consulta (como por ejemplo, desasociar una matriz) y, por lo tanto, ni siquiera tenga un nombre de tabla en la base de datos. Si toma la decisión "absolutamente siempre, getTableName devuelve el alias", entonces al menos los usuarios saben qué esperar; de lo contrario, terminas con que no sea obvio lo que el método debería devolver.

Sin embargo, incluso si asumo que mi reacción visceral es "la implementación correcta", plantea la cuestión de la compatibilidad. Es deseable que sea posible cambiar de otro DBMS a PostgreSQL con la menor inversión posible, si uno de los objetivos de PostgreSQL es crecer en popularidad. Por lo tanto, cosas como "¿cómo otros JDBC implementan las interfaces java.sql?" Se vuelven relevantes. Como dices, existe un marco que tiene expectativas de cómo se debe implementar el ResultSetMetaData, y es probable que no sea el único con ciertas expectativas de cómo se implementarán las interfaces java.sql.

Cualquiera que sea la implementación que terminen eligiendo va a ser una compensación, así que puedo ver por qué "patear la lata por el camino" es su elección. Una vez que eligen la compensación que desean establecer, están bloqueados.

EDITAR: Yo sugeriría que arrojar una excepción con respecto a no implementar sería mejor que simplemente fallar silenciosamente. Espero que los marcos que se basan en una implementación específica de getTableName no tengan mucho uso para la cadena vacía de todos modos, y el error o ellos mismos fallan silenciosamente.

Cuestiones relacionadas