2011-08-28 10 views
36

Imagine Mam zapytanie jakJDBC ResultSet uzyskać kolumn tabeli alias

SELECT * from table1 a, table2 b where (WHATEVER) 

Może obie tabele mają taką samą nazwę kolumny. Tak więc byłoby miło uzyskać dostęp do danych poprzez

resultSet.getString("a.columnName"); 
resultSet.getString("b.columnName"); 

Ale to niszczy mnie i nic nie dostaję. Czytam API, ale tak naprawdę nie mówią o tej sprawie. Czy taki dostawca funkcji jest zależny?

Odpowiedz

39

JDBC będzie po prostu wymienić kolumny, przez co jest określone w zapytaniu - nie wiedzieć o nazwach tabel itp

Masz dwie opcje:

Wariant 1: Nazwa kolumny różnie w zapytaniu, tj

SELECT 
    a.columnName as columnNameA, 
    b.columnName as columnNameB, 
    ... 
from table1 a, table2 b where (WHATEVER) 

następnie w kodzie java odnoszą się do aliasów kolumn:

resultSet.getString("columnNameA"); 
resultSet.getString("columnNameB"); 


Opcja 2: Patrz kolumnie pozycję w wywołaniu API JDBC:

resultSet.getString(1); 
resultSet.getString(2); 

nocie, że API JDBC używa jeden opartych indeksów - czyli liczą od 1 (nie od 0 podobnie jak indeksy java), więc użyj 1 dla pierwszej kolumny, 2 dla drugiej kolumny, itd.


Polecam opcję 1, ponieważ bezpieczniej jest odwoływać się do nazwanych kolumn: Ktoś może zmienić kolejność kolumn w zapytaniu i po cichu złamałby kod (miałby dostęp do niewłaściwej kolumny, ale nie wiedziałby), ale jeśli zmienią nazwy kolumn, przynajmniej otrzymasz wyjątek "brak takiej kolumny" w środowisku wykonawczym.

+0

Okay wygląda jak będę musiał zapomnieć o ładnym * i nazwy wszystkiego i korzystać z dodatkowego mapowanie. –

8

Użyj aliasów kolumn, takich jak SELECT A.ID 'A_ID', B.ID 'B_ID' FROM TABLE1 AS A, TABLE2 AS B... i określ wszystkie kolumny, które pobierasz (jest to dobra praktyka).

0

Możesz używać aliasu na poziomie SQL. Następnie pobierasz dane według indeksów. (Ale to podejście pozwoli konserwacja prawdziwy koszmar)

SELECT a.column, b.column FROM table1 a, table2 b 

String value = rs.getString(1); 
0

Jeden pomysł miałem jest użycie getTableName(iCol) chwycić nazwy tabel dla zduplikowanych nazw kolumn, a następnie owinąć mieszania własnych kluczy (z prefiks nazwy tabeli), który wskazywałby poprawny indeks kolumny i odwoływał się do wartości kolumn w ten sposób. To wymagałoby początkowej pętli przez metadane na początku do konfiguracji. Jedynym problemem, jaki widzę z tym, jest to, że również aliasingujesz nazwy tabel. Nie znalazłem jeszcze sposobu na uzyskanie aliasów nazw tabel od jdbc bez samodzielnego zarządzania nimi podczas budowania instrukcji sql. To rozwiązanie będzie zależało od tego, jaki będzie dla ciebie syntaktyczny zysk.

+0

@Bohemian - możesz użyć funkcji ResultSetMetaData :: getTableName (int), aby uzyskać nazwę tabliny. Nie jestem pewien, czy wynik zależy od implementacji jdbc. https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSetMetaData.html#getTableName(int) – inyourcorner

0

Ok, wydaje się, że nie ma sposobu jak resultSet.getString("a.columnName"); i trzeba aliasu kolumn na poziomie SQL ale ponieważ istnieje getTableName(iCol) metoda Mam nadzieję, że chłopaki z java.sql.ResultSet dodać taką funkcję.

9

ResultSetMetadata.getColumnLabel() jest to, czego potrzebujesz

(edit) próbka przykład, jak stwierdził nahur górski w komentarzu

SELECT * from table1 a, table2 b where (WHATEVER) 

ResultSetMetaData rsmd = rset.getMetaData(); 
rsmd.getColumnLabel(1); 
+1

dlaczego i jak i jaki jest przykład tego działającego? – bharal

+0

tam edytujesz odpowiedź za pomocą przykładowego fragmentu kodu – Mateen

2

Jeśli używasz MySQL wystarczy dodać

&useOldAliasMetadataBehavior=true 

do połączenia connectionString.

Następnie można użyć tego małego pomocnika:

import java.sql.ResultSet; 
import java.sql.ResultSetMetaData; 
import java.sql.SQLException; 
import java.util.HashMap; 
import java.util.Map; 

public class ResultSetHelper { 

    private final Map<String, Integer> columnMap; 

    public ResultSetHelper(ResultSet rs) throws SQLException { 
     this.columnMap = new HashMap<>(); 
     ResultSetMetaData md = rs.getMetaData(); 
     int columnCount = md.getColumnCount(); 
     for (int index = 1; index <= columnCount; index++) { 
      String columnName = md.getColumnLabel(index); 
      if (!columnMap.containsKey(columnName)) { 
       columnMap.put(columnName, index); 
      } 

      String tableAlias = md.getTableName(index); 
      if (tableAlias != null && !tableAlias.trim().isEmpty()) { 
       columnMap.put(tableAlias + "." + columnName, index); 
      } 
     } 
    } 

    public Integer getColumnIndex(String columnName) { 
     return columnMap.get(columnName); 
    } 

    public Integer getColumnIndex(String tableAlias, String columnName) { 
     return columnMap.get(tableAlias + "." + columnName); 
    } 

} 
Powiązane problemy