Java 如何检查 CachedRowSet 中是否存在列名?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/462534/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 14:56:18  来源:igfitidea点击:

How do I check to see if a column name exists in a CachedRowSet?

javajdbcmetadatacachedrowset

提问by WolfmanDragon

I am querying data from views that are subject to change. I need to know if the column exists before I do a crs.get******().I have found that I can query the metadata like this to see if a column exist before I request the data from it.

我正在从可能会更改的视图中查询数据。我需要在执行 a 之前知道该列是否存在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;

Is there a simpler way of checking to see if a column exists?

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

EDIT: It must be database agnostic. That is why I am referencing the CachedRowSetinstead of the database.

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

采纳答案by Jared

There's not a simpler way with the general JDBC API (at least not that I know of, or can find...I've got exactly the same code in my home-grown toolset.)

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

(Your code isn't complete):

(您的代码不完整):

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;

That being said, if you use proprietary, database-specific API's and/or SQL queries, I'm sure you can find more elegant ways of doing the same thing...but you'd have to write custom code for each database you need to deal with. I'd stick with the JDBC APIs, if I were you.

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

Is there something about your proposed solution that makes you think it's incorrect? It seems simple enough to me...

您提出的解决方案是否有一些让您认为它不正确的地方?对我来说似乎很简单......

回答by OscarRyz

Which Database?

哪个数据库?

I think in Oracle there are tables where the columns are listed.

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

I don't remember if it work for views also, but I guess they do, it was something like:

我不记得它是否也适用于视图,但我想它们确实适用,它是这样的:

select colum_name from all_views where view_name like 'myview'

or

或者

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

I don't remember exactly the syntax. You should have spacial permissions though.

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

Every RDBMS should have something similar.

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

You can also perform the query

您还可以执行查询

select * from myView where 1 = 0 ; 

And from the metadata get the columns, if what you want it to avoid fetching the data before to know if the columns are present.

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

回答by Joshua

No, there really isn't a better way. You may want to relook at the problem. If you can redefine the problem, sometimes it makes the solution simpler because the problem has changed.

不,真的没有更好的方法。您可能需要重新审视这个问题。如果你能重新定义问题,有时它会使解决方案更简单,因为问题已经改变。

回答by davek

WARNING: following comment purely from memory without any supporting paperwork :)

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

If I recall correctly there is a mysterious problem that rears its ever-so-ugly-head when the oracle cached rowset implementation is used with connection pooling. There appears to be a silent reference to the connection held within the cached rowset object (even though it's supposed to be disconnected) which closes another connection subsequently opened from pool on garbage collection. For this reason I eventually gave up and wrote my own data object layer (these days I'd hand that over to spring & hibernate).

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

回答by Peter Mullarkey

you could take the shorter approach of using the fact that findColumn() will throw an SQLException for InvalidColumName if the column isn't in the CachedRowSet.

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

for example

例如

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

Likely an abuse of Exception Handling (per EffectiveJava 2nd ed item 57) but it is an alternative to looping through all the columns from the meta data.

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

回答by Lutos?aw

Old thread, but I've just faced the same problem and ended up with an utility function:

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

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

It'd be quite elegent if we wouldn't have to catch exceptions inside a lambda (without some ugly hacks)

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

回答by Ross H

Following on from the top answer in this thread from Jared, and one of its under-rated comments from corsiKa:

继 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");