wake-up-neo.com

JDBC ResultSet ruft Spalten mit Tabellenalias ab

Stellen Sie sich vor, ich hätte eine Anfrage 

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

Möglicherweise haben beide Tabellen den gleichen Spaltennamen. Also ich wäre zwar nett, auf die Daten über zuzugreifen

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

Aber das scheitert an mir und ich bekomme nichts. Ich habe die API gelesen, aber sie sprechen nicht wirklich über diesen Fall. Ist ein solches Feature-Anbieter abhängig?

43
Franz Kafka

JDBC benennt die Spalten einfach nach dem, was in der Abfrage angegeben ist - sie kennt keine Tabellennamen usw.

Sie haben zwei Möglichkeiten:

Option 1: Benennen Sie die Spalten in der Abfrage anders, dh

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

verweisen Sie dann in Ihrem Java-Code auf die Spaltenaliasnamen:

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


Option 2: Lesen Sie in Ihrem Aufruf an die JDBC-API die Spalte position:

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

Beachten Sie, dass die JDBC-API one-based - Indizes verwendet - dh sie zählen von 1 (nicht von 0 wie Java-Indizes). Verwenden Sie also 1 für die erste Spalte, 2 für die zweite Spalte usw


Ich würde Option 1 empfehlen, da es sicherer ist, auf benannte Spalten zu verweisen: Jemand kann die Reihenfolge der Spalten in der Abfrage ändern und würde Ihren Code unbemerkt brechen (Sie würden auf die falsche Spalte zugreifen, wissen aber nicht). Wenn sie jedoch die Spaltennamen ändern, erhalten Sie zur Laufzeit mindestens die Ausnahme "keine solche Spalte". 

45
Bohemian

ResultSetMetadata.getColumnLabel () ist das, was Sie brauchen

(edit) Beispielbeispiel, wie von bharal im Kommentar angegeben

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

ResultSetMetaData rsmd = rset.getMetaData();
rsmd.getColumnLabel(1);
12
Mateen

Verwenden Sie Spaltenaliasnamen wie:

SELECT A.ID 'A_ID', B.ID 'B_ID' FROM TABLE1 AS A, TABLE2 AS B...

Geben Sie alle Spalten an, die Sie abrufen (ist eine bewährte Methode).

Wenn Sie MySQL verwenden, fügen Sie einfach hinzu 

&useOldAliasMetadataBehavior=true

zu Ihrem AnschlussString. 

Danach kannst du diesen kleinen Helfer benutzen:

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

}

Ok, es scheint, als gäbe es keine Methode wie resultSet.getString("a.columnName"); Und Sie müssen Ihre Spalten auf SQL-Ebene als Aliasnamen angeben, Da es sich jedoch um eine getTableName(iCol)-Methode handelt, hoffe ich, dass die Leute bei Java.sql.ResultSet eine solche Funktion hinzufügen.

1
Mostafa

Sie können Alias ​​auf SQL-Ebene verwenden. Dann werden Daten über Indizes abgerufen. (Aber dieser Ansatz macht die Wartung zu einem echten Alptraum)

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

String value = rs.getString(1);
0
Ammar

Ich hatte die Idee, die getTableName(iCol) zu verwenden, um die Tabellennamen für die doppelt benannten Spalten zu ermitteln und dann einen Hash Ihrer eigenen Schlüssel (mit dem Tabellennamenpräfix) zu umschließen, der Sie auf den richtigen Spaltenindex verweist und Ihre Spalte referenzieren würde -Werte so. Dies erfordert eine anfängliche Schleife durch die Metadaten zu Beginn, um sie einzurichten. Das einzige Problem, das ich dabei sehe, ist, dass Sie auch die Tabellennamen aliasieren. Ich muss noch einen Weg finden, diese Tabellennamensaliasnamen von jdbc zu erhalten, ohne sie selbst zu verwalten, wenn Sie die SQL-Anweisung erstellen. Diese Lösung würde davon abhängen, welche syntaktische Auszahlung sich für Sie ergeben würde.

0
inyourcorner