2010-05-31 28 views
67

Ich habe eine Desktop-Anwendung mit einer Datenbank eingebettet. Wenn ich mein Programm ausführe, muss ich prüfen, ob eine bestimmte Tabelle existiert, oder es erstellen, wenn nicht.Überprüfen Sie, ob die Tabelle existiert

Gegeben ein Connection-Objekt namens Conn für meine Datenbank, wie könnte ich dies überprüfen?

+4

möglich Duplikat [Wie kann ich eine SQL-Tabelle Existenz in Java erkennen?] (Http://stackoverflow.com/questions/927807/how-can-i-detect-a-sql-tables-existence -in-java) – finnw

+0

Bitte präzisieren Sie in Ihrer Frage. –

Antwort

57

können Sie die verfügbaren Meta-Daten verwenden:

DatabaseMetaData meta = con.getMetaData(); 
    ResultSet res = meta.getTables(null, null, "My_Table_Name", 
    new String[] {"TABLE"}); 
    while (res.next()) { 
    System.out.println(
     " "+res.getString("TABLE_CAT") 
     + ", "+res.getString("TABLE_SCHEM") 
     + ", "+res.getString("TABLE_NAME") 
     + ", "+res.getString("TABLE_TYPE") 
     + ", "+res.getString("REMARKS")); 
    } 

here Details für mehr sehen. Beachten Sie auch die Vorbehalte in the JavaDoc.

+0

Danke !!!!!! – Dmitry

+8

Sie fordern alle Tabellen vom Server an und durchsuchen diese Namen dann lokal. Das ist nicht sehr effizient, wenn Sie nur überprüfen möchten, ob die Tabelle 'X' existiert. Sie würden das dritte Argument für die 'getTables()' Methode verwenden wollen !!! (anstatt "Null" wie Sie es tun) – peterh

+0

@ nolan6000 - notiert und geändert. Thx –

105
DatabaseMetaData dbm = con.getMetaData(); 
// check if "employee" table is there 
ResultSet tables = dbm.getTables(null, null, "employee", null); 
if (tables.next()) { 
    // Table exists 
} 
else { 
    // Table does not exist 
} 
+3

Stellen Sie sicher, dass bei Verwendung von Tabellennamen keine Musterzeichen wie Unterstriche verwendet werden, z. B. "employee_reports". Ich bin von solchen Situationen überrascht worden, da einige Metadaten-Implementierungen Mustervergleiche verwenden. Am besten überprüfen Sie die Ergebnismenge mit einer einfachen table.equals ("employee_reports") -Anweisung in Ihrem if – Constantin

+0

gleichen Code funktioniert auch für postgres jdbc.Thanks. – Ankur

6

zu Gabys Beitrag hinzufügen, (mein jdbc getTables) für Oracle 10g alle Kappen erfordert arbeiten:

"employee" -> "EMPLOYEE"

Sonst würde ich eine Ausnahme erhalten:

java. sql.SqlExcepcion erschöpfte Ergebnismenge

(obwohl "Mitarbeiter" im Schema ist)

5

Ich finde keine der hier vorgestellten Lösungen, um vollständig zu sein, also werde ich meine eigenen hinzufügen. Nichts Neues hier. Sie können dies aus den anderen vorgestellten Lösungen plus verschiedene Kommentare zusammenfügen.

Es gibt mindestens zwei Dinge, die Sie sicher machen müssen:

  1. Achten Sie darauf, den Tabellennamen übergeben an die getTables() method, eher als einen Nullwert übergeben. Im ersten Fall lassen Sie den Datenbankserver das Ergebnis für Sie filtern, im zweiten fordern Sie eine Liste von alle Tabellen vom Server an und filtern Sie dann die Liste lokal. Ersteres ist viel schneller, wenn Sie nur nach einer Einzeltabelle suchen.

  2. Vergewissern Sie sich, dass der Tabellenname aus dem Resultset mit einem Gleichheitszeichen übereinstimmt. Der Grund ist, dass die getTables() Mustererkennung auf die Abfrage für die Tabelle und das _ Zeichen ein Platzhalter in SQL ist. Angenommen, Sie prüfen, ob eine Tabelle namens EMPLOYEE_SALARY vorhanden ist. Sie erhalten dann eine Übereinstimmung auf zu , was nicht das ist, was Sie wollen.

Ohh, und vergessen Sie nicht, diese Ergebnisse zu schließen. Seit Java 7 möchten Sie dafür eine try-with-resources statement verwenden.

Hier ist eine komplette Lösung:

public static boolean tableExist(Connection conn, String tableName) throws SQLException { 
    boolean tExists = false; 
    try (ResultSet rs = conn.getMetaData().getTables(null, null, tableName, null)) { 
     while (rs.next()) { 
      String tName = rs.getString("TABLE_NAME"); 
      if (tName != null && tName.equals(tableName)) { 
       tExists = true; 
       break; 
      } 
     } 
    } 
    return tExists; 
} 

Sie betrachten wünschen können, was Sie als types Parameter (4 Parameter) übergeben auf Ihrem getTables() Anruf. Normalerweise würde ich einfach unter null gehen, weil Sie sich nicht einschränken wollen. Ein Blick ist so gut wie ein Tisch, oder?Heutzutage können Sie in vielen Datenbanken über eine VIEW aktualisieren, so dass Sie sich nur auf den TABLE-Typ beschränken können, was in den meisten Fällen nicht der richtige Weg ist. YMMV.

+0

Möglicherweise müssen Sie 'tName.equals (tableName)' in 'tName.equals (tableName.toLowerCase())' ändern, es würde nicht funktionieren, wenn 'tableName' in Großbuchstaben wäre. – Searene

0
/** 
* Method that checks if all tables exist 
* If a table doesnt exist it creates the table 
*/ 
public void checkTables() { 
    try { 
     startConn();// method that connects with mysql database 
     String useDatabase = "USE " + getDatabase() + ";"; 
     stmt.executeUpdate(useDatabase); 
     String[] tables = {"Patients", "Procedures", "Payments", "Procedurables"};//thats table names that I need to create if not exists 
     DatabaseMetaData metadata = conn.getMetaData(); 

     for(int i=0; i< tables.length; i++) { 
      ResultSet rs = metadata.getTables(null, null, tables[i], null); 
      if(!rs.next()) { 
       createTable(tables[i]); 
       System.out.println("Table " + tables[i] + " created"); 
      } 
     } 
    } catch(SQLException e) { 
     System.out.println("checkTables() " + e.getMessage()); 
    } 
    closeConn();// Close connection with mysql database 
} 
Verwandte Themen