2010-08-30 110 views
45

由于ResultSet包含从动态SQL返回的数据,如果有任何方法可以确定ResultSet是否包含特定的列名称?例如,如果我运行rs.getString("Column_ABC");但Column_ABC并不存在,它将抛出异常。我如何测试ResultSet是否可以从名为“Column_ABC”的列中获取数据?如何确定列名是否存在于ResultSet中?

+0

可能重复?](http://stackoverflow.com/questions/462534/how-do-i-check-to-see-if-a-column-name-exists-in-a-cachedrowset) – bluish 2015-04-22 08:54:55

回答

67

使用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; 
} 

我不明白的是为什么这个功能会被需要。正在执行的查询或存储过程应该具有已知的结果。查询的列应该是已知的。需要这样的功能可能表明某处存在设计问题。

+0

在TOAD等工具中执行用户查询时,应用程序不知道查询结构,并且必须使用“ResultSetMetaData”。但是,是的,搜索特定的列名是很奇怪的。 – gpeche 2010-08-31 07:05:21

+0

只是在你的例子中评论...你正在检索所有列信息。对于用户查询,我希望这是标准的。这仍然不能搜索是否包含特定列。 – 2010-08-31 11:12:12

+8

这基本上是正确的,但'getColumnName'的参数从1开始不是0.您需要'for(int x = 1; x <= columns; x ++)' – 2012-05-03 14:33:37

-13

如果不是rs.getString( “Column_ABC”)=没有那么 '在这里你的代码

+7

这是一个坏主意,这也是错误的。当列不存在时,它不会返回任何内容。它抛出一个SQLException,你必须捕捉和处理。你不应该使用这样的简单检查来抛出异常。你应该总是寻找一种实际上会返回一个布尔值的方法 - 这实际上会执行一个适当的检查。 – 2010-08-30 11:41:27

4

不知道这是否比Erick的答案更有效或更低效,但它更容易。

String str; 

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

毫无疑问,它更容易理解。但是,无论我没有看到JDBC驱动程序返回“SQLServer”异常,ResultSet方法在列名无效或发生更通用的SQL错误时都会返回SQLException(这会导致知道发生了什么:如果列名错误或发生实际错误)+ info @ [ResultSet Javadoc](http://docs.oracle.com/javase/8/docs/api/java/sql/ResultSet.html#getObject-java.lang .String-) – 2014-08-12 13:50:42

+17

-1只能在特殊情况下使用异常,然后应该记录日志。简单的出路往往会创建难以理解和维护的代码。如果您在使用服务器端结果集并在进行此调用之前失去了与数据库的连接,那么即使该列存在,此方法也会引发异常。如果代码使用此检查(例如)来确定整个数据库是否需要初始化,则此类方案可能会导致灾难性后果。 – 2014-08-14 11:18:03

+0

非常感谢João。我的意思是SQLException。试图选择一个通用的。 – Zip184 2014-08-20 12:19:23

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; 
    } 
} 

在Java版本> = 7你在ResultSet中#getObject方法路过类类型的选项

的[我如何检查,看是否有列名CachedRowSet中存在
+0

这应该是正确的答案。这是一种安全的方式,可以根据行提供get对象类型,填充/映射对象,而不管它是否被填充,客户端或底层业务逻辑应该知道应该期待什么,并且安全地检查它的数据。 – thekevshow 2016-09-30 05:45:42

+0

我不同意,埃里克罗伯森解释了为什么在上面的答案的评论。 – 2016-12-14 06:47:23

+0

尽管如此,它滥用异常处理背后的想法。 – Benedictus 2017-11-10 18:40:57

相关问题