2012-02-12 4 views
6

、私は次のコードを見つけました:postgresqlのjdbcドライバの "ResultSet.getMetaData.getTableName(col)"は常に空文字列を返していますか?私は、PostgreSQLを使用する場合

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ドライバの正しい実装についてどう思いますか?空の文字列、基になるテーブル名などを返しますか?

答えて

3

空の文字列を返すのは明らかに、テーブル名が空の文字列であるとは考えられないため、インターフェイスの実装が間違っていると言えます。

私が苦労していると思う問題は、現在の実装が間違っている間に、実装を選択すると、動作の依存関係を破ることが受け入れられると判断するまでそれに固執することです。したがって、彼らは名前が明白であるメソッドを追加し、ほとんどのユーザーが来ると予想していたデータをgetTableNameから提供することを選択し、何を返すべきか、パッチまで合意に達するまで、getTableNameメソッドの明らかに壊れた実装を残しますコンセンサスを実現するために提出されます。

私の反応は、getTableNameというメソッドは、そのテーブルに使用されているエイリアスを返さなければならないということです。テーブルはそれ自身と結合することができ、そのエイリアスを使用すると、参照されているものを識別することができます。テーブルがクエリ内で生成されている可能性があります(配列のネスト解除など)。したがって、データベースにもテーブル名はありません。あなたが「絶対に常に」という決定をした場合、getTableNameはエイリアスを返します。そして、少なくともユーザは何を期待するかを知っています。それ以外の場合は、メソッドが返すべき内容が明白ではありません。

しかし、私の腸の反応が「正しい実装」であると仮定しても、互換性の問題が生じます。 PostgreSQLの目標の1つが成長するなら、可能な限り少ない投資で別のDBMSからPostgreSQLに切り替えることが可能であることが望ましいです。したがって、「他のJDBCがjava.sqlインタフェースをどのように実装するのか」などの関連性が高くなります。あなたが言うように、ResultSetMetaDataの実装方法を期待するフレームワークが存在し、java.sqlインターフェイスがどのように実装されるかについての特定の期待を持った唯一のものではない可能性があります。

どちらの実装が最終的にトレードオフになるのかは分かりませんが、なぜ「キック・ザ・ノン・ザ・ロード」が選択されたのか分かります。

EDIT:実装されていないことに関する例外をスローすると、単に黙って失敗するよりも優れていることが示唆されます。私は、getTableNameの特定の実装に依存しているフレームワークは、とにかく空の文字列にあまり使用されず、エラーまたは自分自身が黙って失敗することを期待しています。

関連する問題