postgresql的jdbc驱动程序的“ResultSet.getMetaData.getTableName(col)”是否总是返回空字符串是否正确?

问题描述:

当我使用PostgreSQL,我发现下面的代码:postgresql的jdbc驱动程序的“ResultSet.getMetaData.getTableName(col)”是否总是返回空字符串是否正确?

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总是返回一个空字符串的方法。

的源代码是:

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)”应 查询不是底层表名返回的别名。但是很难实现,所以最好将它留空。

此外,他们给了一个方法来获取表名称,使用方法:

PGResultSetMetaData.getBaseTableName() 

样品:

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驱动程序的正确实现是什么?返回一个空字符串,底层表名或其他东西?

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

,我相信他们正在挣扎的问题是,虽然他们目前的实现是错误的,一旦他们选择他们将与它卡住的实现,直到他们决定上的行为打破依赖关系是可以接受的。因此,他们选择添加一个名称明确的方法,并提供大多数用户期望来自getTableName的数据,并且在执行getTableName方法时明显破坏了该方法,直到就应该返回的内容达成某种共识或直到获得补丁被提交,实现共识。

我的直觉反应是方法getTableName应该返回用于该表的别名。一张表可以与自己连接,并且使用别名可以让你识别哪个被引用。一个表可能已经在查询中生成(例如unnesting一个数组),因此在数据库中甚至没有表名。如果您决定“绝对总是,getTableName返回别名”,那么至少用户知道该期待什么;否则,你最终不明白该方法应该返回什么。

然而,即使我认为我的直觉反应是“正确的实现”,它提出了兼容性的问题。如果PostgreSQL的目标之一越来越受欢迎,那么希望能够用尽可能少的投资从另一个DBMS切换到PostgreSQL。因此,诸如“其他JDBC如何实现java.sql接口?”变得相关。正如你所说,一个框架存在具有的ResultSetMetaData应该如何实现的预期,很可能不是唯一一个与java.sql接口将如何实现一定的期望。

他们最终无论执行了选择将是一个权衡,所以我能看到为什么“踢罐头在路上”是他们的选择。一旦他们选择他们想要做的权衡,他们被锁定在

编辑:我的建议是抛出关于不实施会比只是默默未能更好例外。我想到的是依赖于特定的实施getTableName框架不会对空字符串多大用处反正,要么错误或自己默默地失败。

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