首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JDBC DatabaseMetaData.getColumns()返回重复列

JDBC DatabaseMetaData.getColumns()返回重复列
EN

Stack Overflow用户
提问于 2009-10-21 14:30:12
回答 5查看 41.3K关注 0票数 18

我正忙于编写一段代码,以便从Oracle数据库中获取表的列名。我想出的代码如下所示:

代码语言:javascript
运行
复制
DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection(
  "jdbc:oracle:thin:@<server>:1521:<sid>", <username>, <password>);

DatabaseMetaData meta = conn.getMetaData();
ResultSet columns = meta.getColumns(null, null, "EMPLOYEES", null);
int i = 1;
while (columns.next())
{
  System.out.printf("%d: %s (%d)\n", i++, columns.getString("COLUMN_NAME"), 
    columns.getInt("ORDINAL_POSITION"));
}

当我意外地运行这段代码时,返回了太多的列。仔细观察发现,ResultSet包含所有列的重复集,即每个列被返回两次。这是我得到的输出:

代码语言:javascript
运行
复制
1: ID (1)
2: NAME (2)
3: CITY (3)
4: ID (1)
5: NAME (2)
6: CITY (3)

当我使用Oracle SQL Developer查看表时,它会显示该表只有三列(ID、NAME、CITY)。我已经针对我的数据库中的几个不同的表尝试了这段代码,有些非常好,而另一些则表现出了这种奇怪的行为。

Oracle JDBC驱动程序中会有错误吗?还是我在这里做错了什么?

更新:多亏了,我现在有了一种检索列名的替代方法。您可以从ResultSet中获得它们,如下所示:

代码语言:javascript
运行
复制
DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@<server>:1521:<sid>", <username>, <password>);

Statement st = conn.createStatement();
ResultSet rset = st.executeQuery("SELECT * FROM \"EMPLOYEES\"");
ResultSetMetaData md = rset.getMetaData();
for (int i=1; i<=md.getColumnCount(); i++)
{
    System.out.println(md.getColumnLabel(i));
}

这似乎是很好的工作,没有重复的返回!对于那些想知道的人:根据这个博客,您应该使用getColumnLabel()而不是getColumnName()。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-10-21 14:37:18

在oracle中,Connection.getMetaData()返回整个数据库的元数据,而不仅仅是连接到的模式。因此,当您将null作为meta.getColumns()的前两个参数提供时,您并不是只过滤模式的结果。

您需要将Oracle的名称提供给meta.getColumns()的前两个参数之一,可能是第二个参数。

代码语言:javascript
运行
复制
meta.getColumns(null, "myuser", "EMPLOYEES", null);

不得不这样做有点烦人,但是Oracle人员选择了实现他们的JDBC驱动程序的方式。

票数 28
EN

Stack Overflow用户

发布于 2009-10-22 18:55:17

这并不能直接回答您的问题,但另一种方法是执行查询:

代码语言:javascript
运行
复制
select * from tablename where 1 = 0

这将返回一个ResultSet,即使它没有选择任何行。结果集元数据将匹配您从其中选择的表。取决于你在做什么,这可能会更方便。tablename可以是您可以选择的任何东西--您不需要让情况正确,也不必担心它在什么模式中。

票数 16
EN

Stack Overflow用户

发布于 2011-08-31 19:28:24

在更新你的问题时,我注意到你漏掉了肯斯特答案的一个关键部分。他指定了'where 1= 0‘的'where’子句,但你没有。这一点很重要,因为如果关闭它,oracle将尝试返回整个表。如果你不把所有的记录都取下来,甲骨文就会抓住它们,等待你翻阅它们。添加where子句仍然为您提供元数据,但没有任何开销。

另外,我个人使用了“where rownum <1”,因为oracle立即知道所有行都超过了这个值,而且我不确定不尝试测试“1=0”的每个记录是否明智。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1601203

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档