2012-02-12 22 views
6

Gdy używam PostgreSQL, znalazłem następujący kod:Czy to prawda, że ​​"ResultSet.getMetaData.getTableName (col)" sterownika jdbc postgresql zawsze zwraca pusty ciąg znaków?

Statement stmt = conn.createStatement(); 
ResultSet rs = stmt.executeQuery("select * from t"); 

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

Drukuje pusty ciąg.

Sprawdziłem kod źródłowy i stwierdziłem, że metoda org.postgresql.jdbc2.AbstractJdbc2ResultSetMetaData#getTableName zawsze zwraca pusty ciąg znaków.

Kod źródłowy jest:

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 ""; 
    } 
} 

Widać to po prostu zwrócić "".

znalazłem dyskusję na ten temat można znaleźć na stronie: http://archives.postgresql.org/pgsql-jdbc/2009-12/msg00100.php

uważają „rs.getMetaData.getTableName (COL)” powinien zwrócić alias w zapytanie nie podstawowa nazwa tabeli. Ale trudno to wdrożyć, więc lepiej zostawić to puste.

także dali sposób, aby uzyskać nazwę tabeli, należy:

PGResultSetMetaData.getBaseTableName() 

Próbka:

ResultSet rs = stmt.executeQuery("select * from x"); 
// convert it to PGResultSetMetaData 
PGResultSetMetaData meta = (PGResultSetMetaData)rs.getMetaData(); 
String tableName = meta.getBaseTableName(1); 

Teraz można drukować poprawną nazwę tabeli.

Nie wiem, czy implementacja PostgreSQL jest poprawna, ale zwrócenie podstawowej nazwy tabeli jest o wiele bardziej przydatne niż pusty ciąg, a większość innych baz danych udostępnia nazwę tabeli zamiast pustego ciągu.

Mam problem z wykorzystaniem ram anorm play2 z postgesql: Play2's anorm can't work on postgresql, ale to działa dobrze na innych bazach danych.

Jak myślisz, jaka jest prawidłowa implementacja sterownika jdbc postgresql? Zwrócić pusty ciąg, nazwę tabeli podstawowej lub coś innego?

Odpowiedz

3

Powiedziałbym, że zwracanie pustego ciągu jest oczywiście nieprawidłową implementacją interfejsu, ponieważ nazwa tabeli nigdy nie może być traktowana jako pusty ciąg.

Problem, który, jak sądzę, zmaga się z tym, że podczas gdy ich obecna implementacja jest nieprawidłowa, po wybraniu implementacji zostaną zablokowane, dopóki nie zdecydują, że zerwanie zależności od zachowania jest akceptowalne. Dlatego wybierają metodę, której nazwa jest jednoznaczna i dostarczają dane, które większość użytkowników oczekiwała od getTableName, i pozostawiają oczywiście złamaną implementację metody getTableName, dopóki nie zostanie osiągnięty konsensus co do tego, co powinien powrócić, lub do momentu, kiedy łatka został złożony, który wdraża konsensus.

Moja reakcja polega na tym, że metoda getTableName powinna zwrócić alias używany dla tej tabeli. Tabelę można połączyć ze sobą, a użycie tego aliasu pozwoliłoby zidentyfikować, do którego odniesienia się odwołano. W zapytaniu mogła zostać wygenerowana tabela (taka jak anulowanie tablicy), a zatem nawet nie ma nazwy tabeli w bazie danych. Jeśli podejmiesz decyzję "absolutnie zawsze, getTableName zwraca alias", wtedy przynajmniej użytkownicy wiedzą, czego się spodziewać; w przeciwnym razie nie będzie oczywiste, jaka metoda powinna zostać zwrócona.

Jednak nawet jeśli przyjmuję, że moja reakcja jelitowa jest "poprawną implementacją", to podnosi ona kwestię kompatybilności. Pożądane jest, aby możliwe było przejście z innego systemu DBMS do PostgreSQL przy jak najmniejszych inwestycjach, jeśli jednym z celów PostgreSQL jest wzrost popularności. Dlatego takie rzeczy jak "jak inne JDBC implementują interfejsy java.sql?" Stają się istotne. Tak jak mówisz, istnieje struktura, która ma oczekiwania co do sposobu implementacji ResultSetMetaData i prawdopodobnie nie jest jedynym, który ma pewne oczekiwania co do sposobu implementacji interfejsów java.sql.

Bez względu na to, w jaki sposób ich wybór zostanie zakończony, będzie kompromisem, więc widzę, dlaczego "kopnij puszkę w dół drogi" jest ich wyborem. Po wybraniu kompromisu, który chcą wprowadzić, są one zablokowane.

EDYCJA: Proponuję, aby zgłoszenie wyjątku dotyczącego braku implementacji było lepsze niż zwykłe niepowodzenie. Oczekuję, że ramy, które opierają się na konkretnej implementacji getTableName, i tak nie będą miały wiele zastosowań dla pustego ciągu znaków, a błąd albo same się nie powiedzie.

Powiązane problemy