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

2022-09-02 19:29:56

我忙于从Oracle数据库获取表的列名的一段代码。我想出的代码如下所示:

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 包含所有列的重复集,即每列都返回两次。这是我得到的输出:

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 驱动程序中是否存在错误?还是我在这里做错了什么?


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

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()。


答案 1

在 oracle 中,返回整个数据库的元数据,而不仅仅是您碰巧连接到的模式。因此,当您将 前两个参数提供给 时,您不会仅筛选架构的结果。Connection.getMetaData()nullmeta.getColumns()

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

meta.getColumns(null, "myuser", "EMPLOYEES", null);

这样做有点令人讨厌,但这就是Oracle人员选择实现其JDBC驱动程序的方式。


答案 2

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

select * from tablename where 1 = 0

这将返回一个 ResultSet,即使它不选择任何行。结果集元数据将与您从中选择的表匹配。根据您正在做的事情,这可能更方便。 可以是您可以选择的任何内容 - 您不必正确处理大小写或担心它所在的架构。tablename


推荐