首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >postgresql的jdbc driver的"ResultSet.getMetaData.getTableName(col)“总是返回空字符串,这是正确的吗?

postgresql的jdbc driver的"ResultSet.getMetaData.getTableName(col)“总是返回空字符串,这是正确的吗?
EN

Stack Overflow用户
提问于 2012-02-13 00:40:00
回答 2查看 3.4K关注 0票数 7

当我使用postgresql时,我发现了以下代码:

代码语言:javascript
复制
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from t");

String tableName = rs.getMetaData().getTableName(1);
System.out.println(tableName);

它打印一个空字符串。

所以我检查了源代码,发现org.postgresql.jdbc2.AbstractJdbc2ResultSetMetaData#getTableName方法总是返回一个空字符串。

源码是:

代码语言:javascript
复制
public abstract class AbstractJdbc2ResultSetMetaData implements PGResultSetMetaData {

    /*
     * @param column the first column is 1, the second is 2...
     * @return column name, or "" if not applicable
     * @exception SQLException if a database access error occurs
     */
    public String getTableName(int column) throws SQLException
    {
        return "";
    }
}

您可以看到它只返回一个""

我找到了关于这方面的讨论,请参阅:http://archives.postgresql.org/pgsql-jdbc/2009-12/msg00100.php

他们认为"rs.getMetaData.getTableName(col)“应该在查询中返回别名,而不是底层的表名。但是这很难实现,所以最好把它留空。

他们还给出了一个获取表名的方法,使用:

代码语言:javascript
复制
PGResultSetMetaData.getBaseTableName() 

示例:

代码语言:javascript
复制
ResultSet rs = stmt.executeQuery("select * from x");
// convert it to PGResultSetMetaData 
PGResultSetMetaData meta = (PGResultSetMetaData)rs.getMetaData(); 
String tableName = meta.getBaseTableName(1);

现在,它可以打印正确的表名。

我不知道postgresql的实现是否正确,但返回底层表名要比空字符串有用得多,而且,大多数其他数据库都提供了底层表名而不是空字符串。

我在使用play2的anorm框架和postgesql:Play2's anorm can't work on postgresql时遇到了问题,但它在其他数据库上工作得很好。

你认为postgresql的jdbc驱动程序的正确实现是什么?返回空字符串、基础表名或其他内容?

EN

回答 2

Stack Overflow用户

发布于 2013-01-08 02:28:42

我要说的是,返回一个空字符串显然是接口的一个不正确的实现,因为表名永远不能被认为是一个空字符串。

我认为他们正在努力解决的问题是,虽然他们目前的实现是错误的,但一旦他们选择了一个实现,他们就会一直坚持下去,直到他们决定打破对行为的依赖是可以接受的。因此,他们选择添加一个名称明确的方法,并提供大多数用户期望来自getTableName的数据,并保留getTableName方法的明显损坏的实现,直到就其应该返回的内容达成某种共识,或者直到提交实现该共识的补丁。

我的直觉反应是getTableName方法应该返回用于该表的别名。表可以与自身联接,使用别名可以识别引用的是哪个表。查询中可能已经生成了一个表(例如取消数组的嵌套),因此在数据库中甚至没有表名。如果你决定“绝对总是,getTableName返回别名”,那么至少用户知道应该返回什么;否则,你最终会发现方法应该返回什么并不明显。

然而,即使我假设我的直觉反应是“正确的实现”,它也提出了兼容性问题。如果PostgreSQL的目标之一是增加受欢迎程度,那么可以尽可能少的投资从另一个数据库管理系统切换到PostgreSQL是可取的。因此,像“其他JDBCs如何实现java.sql接口?”变得相关。正如您所说,存在一个对如何实现ResultSetMetaData有期望的框架,而且它可能不是唯一一个对如何实现java.sql接口有一定期望的框架。

无论他们最终选择哪种实现,都将是一种权衡,所以我可以理解为什么“把罐子踢下去”是他们的选择。一旦他们选择了他们想要做的权衡,他们就被锁定了。

编辑:我建议抛出一个关于未实现的异常,总比默默地失败要好。我希望依赖于特定getTableName实现的框架无论如何都不会对空字符串有太大的用处,或者错误或者它们自己都会默默地失败。

票数 3
EN

Stack Overflow用户

发布于 2013-12-27 18:37:26

这似乎会在下一个版本中改变:https://github.com/pgjdbc/pgjdbc/pull/107

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

https://stackoverflow.com/questions/9250517

复制
相关文章

相似问题

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