Java 如何确定结果集中是否存在列名?

Java 如何确定结果集中是否存在列名?,java,jdbc,resultset,Java,Jdbc,Resultset,由于ResultSet包含从动态SQL返回的数据,是否有任何方法确定ResultSet是否包含特定的列名 例如,如果我运行rs.getString(“Column\u ABC”),但“Column\u ABC”实际上并不存在,它将抛出异常 如何测试结果集是否可以从名为“column\u ABC”的列中获取数据?如果不是rs.getString(“column\u ABC”)=则为空 '此处的代码使用ResultSetMetaData类。 public static boolean hasColu

由于
ResultSet
包含从动态SQL返回的数据,是否有任何方法确定
ResultSet
是否包含特定的列名

例如,如果我运行
rs.getString(“Column\u ABC”)
,但
“Column\u ABC”
实际上并不存在,它将抛出异常

如何测试
结果集
是否可以从名为
“column\u ABC”
的列中获取数据?

如果不是rs.getString(“column\u ABC”)=则为空
'此处的代码使用
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;
}
public静态布尔hasColumn(ResultSet rs,String columnName)抛出SQLException{
ResultSetMetaData rsmd=rs.getMetaData();
int columns=rsmd.getColumnCount();

对于(intx=1;x不确定这是否比Erick的答案更有效,但更简单

String str;

try {
    str = rs.getString(columnName);
} catch (java.sql.SQLException e) {
    str = null;
}
/**
*如果结果集中不存在列,则返回默认值
* 
*@param-rs
*@param-columnLabel
*@param defaultValue
*@返回
*/
@抑制警告(“未选中”)
私有静态T getValueFromResultSet(最终结果集),
字符串columnLabel,T默认值){
试一试{
返回(T)rs.getObject(columnLabel);
}捕获(SQLE异常){
返回默认值;
}
}

在java版本>=7中,您可以选择在ResultSet#getObject方法中传递类类型

ResultSet.getColumnMetaData().contains(columnName)

这是一个坏主意,也是错误的。当列不存在时,它不会返回任何内容。它会抛出一个SQLException,您必须捕获并处理它。您永远不应该将抛出的异常用于这样一个简单的检查。您应该始终寻找一个实际返回布尔值的方法—实际上是p的方法执行适当的检查。这基本上是正确的,但是
getColumnName
将其参数从1开始,而不是从0开始。您需要
进行检查(int x=1;x搜索列名并不奇怪。在一个高度动态的、用户可配置的系统中,列集合可能会根据用户的选择而变化很大。是的,可以确定列集合,但假设它总是硬编码的,因此已知的列集合是不正确的。如果您感兴趣,可以使用
ResultSetMetaData.getColumnLabel
获取SQL查询的
as
子句定义的名称。我建议使用
equalsIgnoreCase
检查名称是否相同。在我的示例中,查询中有一个小写列名,从
getColumnName()返回为大写
function是的,DB模式应该是众所周知的。但是,您可能会遇到这样的情况:一个存储过程从一个
连接返回一列,而另一个存储过程不返回该列。只执行所需的连接,而不是选择具有默认值的不必要列来匹配t您的应用程序可能使用的理论架构。通过使用类似
rs.containsColumn(x)
,一个方法可以读取任一存储过程的结果,而不是第二个方法的
rs.get***()
在其他方面与第一个相同。否?毫无疑问,这更容易理解。但是,尽管我没有看到JDBC驱动程序返回“SQLServer”异常,但如果列名无效或发生更一般的SQL错误,ResultSet方法将返回SQLException(这使得了解发生了什么困难:列名是否错误或是否发生了实际错误)+info@-1异常只应在异常情况下使用,然后应记录它们。采取简单的方法可能会创建难以理解和维护的代码。如果您使用的是服务器端resultset,并且在进行此调用之前与数据库的连接断开,则此方法将抛出异常,即使列存在。如果代码使用此检查,这种类型的场景可能导致灾难性后果(例如)确定整个数据库是否需要初始化。谢谢João,你说得对。我指的是SQLException。尝试选择一个通用的。这应该是正确的答案。这是一种安全的方法,可以提供从行获取对象类型,填充/映射对象,而不管对象是否要填充、客户端或底层业务逻辑我不同意,Erick Robertson在上面答案的评论中解释了原因。虽然这样做有效,但它滥用了异常处理背后的思想。@Mjurez,
findColumn
命令返回在这种情况下并不重要。应该被忽略。这个
方法肯定在这里不总是返回true。
findColumn
如果找不到该列,则抛出SQLException。此答案似乎没有问题。是否可以根据变量名修改答案?是否还可以解释其工作原理?
ResultSet
接口没有
getColumnMetaData
方法
private boolean isThere(ResultSet rs, String column){
    try{
        rs.findColumn(column);
        return true;
    } catch (SQLException sqlex){
        logger.debug("column doesn't exist {}", column);
    }

    return false;
}
private boolean isThere(ResultSet rs, String column){
    try{
        rs.findColumn(column);
        return true;
    } catch (SQLException sqlex){
        logger.debug("column doesn't exist {}", column);
    }

    return false;
}