2010-08-30 22 views
45

Como el ResultSet contiene los datos devueltos desde el SQL dinámico, si hay algún método para determinar si el ResultSet contiene un nombre de columna en particular? Por ejemplo, si ejecuto rs.getString("Column_ABC"); pero Column_ABC realmente no existe, arrojará la excepción. ¿Cómo puedo probar si el ResultSet puede obtener datos de una columna llamada "Column_ABC"?¿Cómo puedo determinar si el nombre de la columna existe en el ResultSet?

+0

posible duplicado de [Cómo puedo comprobar para ver si existe un nombre de columna en una CachedRowSet ?] (http://stackoverflow.com/questions/462534/how-do-i-check-to-see-if-a-column-name-exists-in-a-cachedrowset) – bluish

Respuesta

67

Utilice la clase ResultSetMetaData.

public static boolean hasColumn(ResultSet rs, String columnName) throws SQLException { 
    ResultSetMetaData rsmd = rs.getMetaData(); 
    int columns = rsmd.getColumnCount(); 
    for (int x = 1; x <= columns; x++) { 
     if (columnName.equals(rsmd.getColumnName(x))) { 
      return true; 
     } 
    } 
    return false; 
} 

Lo que no entiendo es por eso que nunca sería necesaria esta función. La consulta o el procedimiento almacenado que se está ejecutando debe tener resultados conocidos. Las columnas de la consulta deben ser conocidas. Necesitar una función como esta puede ser una señal de que hay un problema de diseño en alguna parte.

+0

Al ejecutar consultas de usuario en herramientas como TOAD, la aplicación no conoce la estructura de consulta y debe usar 'ResultSetMetaData'. Pero sí, buscar un nombre de columna en particular es extraño. – gpeche

+0

Solo comentando ... en su ejemplo, está recuperando toda la información de la columna. Para una consulta de usuario, espero que esto sea estándar. Esto todavía no está buscando para ver si se incluye una columna específica. –

+8

Esto es básicamente correcto, pero 'getColumnName' toma su parámetro a partir de 1 no 0. Necesitas' for (int x = 1; x <= columns; x ++) ' –

-13

si no rs.getString ("Column_ABC") = nada, entonces 'aquí código

+7

Esta es una mala idea, y también está mal. Cuando una columna no existe, no devuelve nada. Lanza una SQLException, que debes atrapar y manejar. Nunca debe usar una excepción lanzada para una verificación simple como esta. Siempre debe buscar un método que realmente devuelva un valor booleano, algo que realmente realizará una verificación adecuada. –

4

No estoy seguro de si esto es más o menos eficiente que la respuesta de Erick, pero es más fácil.

String str; 

try { 
    str = rs.getString(columnName); 
} catch (java.sql.SQLException e) { 
    str = null; 
} 
+1

Es, sin duda, más fácil de entender. Sin embargo, y sin importar el hecho de que no veo el controlador JDBC devolviendo las excepciones "SQLServer", los métodos ResultSet devuelven SQLException si el nombre de la columna no es válido o si se produce un error de SQL más genérico (lo que dificulta el trabajo de saber qué sucedió: si el nombre de la columna es incorrecto o si se produjo un error real) + info @ [ResultSet Javadoc] (http://docs.oracle.com/javase/8/docs/api/java/sql/ResultSet.html#getObject-java.lang .String-) –

+17

-1 Las excepciones deben usarse solo en circunstancias excepcionales, y luego deben registrarse. Tomar la salida más fácil tiende a crear código que es difícil de entender y mantener. Si está utilizando un conjunto de resultados del lado del servidor y perdió la conexión a la base de datos antes de realizar esta llamada, este método emitirá una excepción incluso si la columna existe. Este tipo de escenario puede generar consecuencias desastrosas si el código usa esta verificación (por ejemplo) para determinar si toda la base de datos necesita inicialización. –

+0

Gracias João tienes razón. Quise decir SQLException. Intenté elegir uno genérico. – Zip184

0
/** 
* returns default value if column is not present in resultset 
* 
* @param rs 
* @param columnLabel 
* @param defaultValue 
* @return 
*/ 
@SuppressWarnings("unchecked") 
private static <T> T getValueFromResultSet(final ResultSet rs, 
     String columnLabel, T defaultValue) { 
    try { 
     return (T) rs.getObject(columnLabel); 
    } catch (SQLException e) { 
     return defaultValue; 
    } 
} 

En la versión Java> = 7 tiene una opción de tipo Class paso en el método ResultSet # getObject

+0

Esta debería ser la respuesta correcta. Esta es una forma segura de proporcionar un tipo de objeto get desde una fila, para llenar/mapear un objeto independientemente de si debe llenarse o no, el cliente o la lógica de negocio subyacente debe saber qué esperar y verificar su seguridad con los datos . – thekevshow

+0

No estoy de acuerdo, Erick Robertson explica por qué en los comentarios de la respuesta anterior. –

+0

Mientras esto funciona, se abusa de la idea detrás del manejo de excepciones. – Benedictus

Cuestiones relacionadas