10

我正在从可能发生变化的视图中查询数据。在执行crs.get******().

我发现我可以像这样查询元数据以查看列是否存在,然后再从它请求数据:

ResultSetMetaData meta = crs.getMetaData();
int numCol = meta.getColumnCount();

for (int i = 1; i < numCol + 1; i++) 
    if (meta.getColumnName(i).equals("name"))
        return true;

有没有更简单的方法来检查列是否存在?


编辑

它必须与数据库无关。这就是为什么我引用CachedRowSet而不是数据库。

4

7 回答 7

10

通用 JDBC API 没有更简单的方法(至少我不知道,或者找不到......我在自己开发的工具集中有完全相同的代码。)

您的代码不完整:

ResultSetMetaData meta = crs.getMetaData();
int numCol = meta.getColumnCount();

for (int i = 1; i < numCol + 1; i++) {
    if (meta.getColumnName(i).equals("name")) {
        return true;
    }
}

return false;

话虽如此,如果您使用专有的、特定于数据库的 API 和/或 SQL 查询,我相信您可以找到更优雅的方式来做同样的事情。但是您必须为需要处理的每个数据库编写自定义代码。如果我是你,我会坚持使用 JDBC API。

您提出的解决方案有什么地方让您认为它不正确吗?这对我来说似乎很简单。

于 2009-01-20T18:50:00.057 回答
8

如果列不在 CachedRowSet 中,您可以采用更短的方法,即 findColumn() 将为 InvalidColumName 抛出 SQLException。

例如

 try {
     int foundColIndex = results.findColumn("nameOfColumn");
} catch {
  // do whatever else makes sense
}

可能是对异常处理的滥用(根据 EffectiveJava 第 2 版第 57 条),但它是循环遍历元数据中所有列的替代方法。

于 2011-01-26T22:54:31.723 回答
1

哪个数据库?

我认为在 Oracle 中有列出列的表。

我不记得它是否也适用于视图,但我想它们确实有效,类似于:

select colum_name from all_views where view_name like 'myview'

或者

select name from all_objects where object_name like 'myview' and object_type='view'

我不记得确切的语法。不过,您应该具有空间权限。

每个 RDBMS 都应该有类似的东西。

您还可以执行查询

select * from myView where 1 = 0 ; 

并从元数据中获取列,如果您希望它避免在知道列是否存在之前获取数据。

于 2009-01-20T18:46:42.200 回答
1

不,真的没有更好的办法。你可能想重新审视这个问题。如果您可以重新定义问题,有时它会使解决方案变得更简单,因为问题已经发生了变化。

于 2009-01-20T18:53:27.757 回答
0

警告:以下评论纯粹来自记忆,没有任何支持性文书工作:)

如果我没记错的话,当 oracle 缓存行集实现与连接池一起使用时,有一个神秘的问题会引起它的丑陋。似乎有对缓存行集对象中保存的连接的静默引用(即使它应该断开连接),它关闭了随后在垃圾收集池中打开的另一个连接。出于这个原因,我最终放弃并编写了自己的数据对象层(这些天我将其交给 spring & hibernate)。

于 2009-10-08T18:34:40.987 回答
0

旧线程,但我刚刚遇到了同样的问题并最终得到了一个实用函数:

private Set<String> getColumnNames(ResultSet cached) throws SQLException {
    ResultSetMetaData metaData = cached.getMetaData();
    return IntStream.range(1, metaData.getColumnCount())
                    .mapToObj(i -> {
                        try {
                            return metaData.getColumnName(i);
                        } catch (SQLException e) {
                            throw new RuntimeException(e);
                        }
                    }).collect(toSet());
}

如果我们不必在 lambda 中捕获异常(没有一些丑陋的 hack),那将是非常优雅的

于 2018-06-07T12:00:11.260 回答
0

继 Jared 的这个帖子中的最佳答案,以及 corsiKa 的一个被低估的评论:

ResultSetMetaData meta = crs.getMetaData();
int numCol = meta.getColumnCount();
Set<String> columns = new HashSet<>;

for (int i = 1; i <= numCol; i++) 
{
    columns.add(meta.getColumnName(i));    
}


return columns.contains("name");
于 2019-09-25T12:25:34.130 回答