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

发布于 2024-07-12 00:34:09 字数 441 浏览 7 评论 0原文

我正在从可能发生变化的视图中查询数据。 在执行 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 而不是数据库。

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:

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 CachedRowSet instead of the database.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

ζ澈沫 2024-07-19 00:34:09

通用 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。

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

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.)

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. Bbut 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.

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

浮华 2024-07-19 00:34:09

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

例如

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

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

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.

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.

若无相欠,怎会相见 2024-07-19 00:34:09

哪个数据库?

我认为在 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 ; 

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

Which Database?

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

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.

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.

不知所踪 2024-07-19 00:34:09

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

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.

尐偏执 2024-07-19 00:34:09

警告:以下评论纯粹是凭记忆而没有任何支持文件:)

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

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).

七七 2024-07-19 00:34:09

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

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 内的异常(没有一些丑陋的黑客),那就非常优雅了

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)

阳光下的泡沫是彩色的 2024-07-19 00:34:09

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

Following on from the top answer in this thread from Jared, and one of its under-rated comments from 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");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文