2010-05-31 71 views
67

Tengo una aplicación de escritorio con una base de datos incrustada en ella. Cuando ejecuto mi programa, necesito verificar que exista una tabla específica, o crearla si no.Comprobar si existe tabla

Dado un objeto Connection llamado conn para mi base de datos, ¿cómo podría verificar esto?

+4

posible duplicado de [¿Cómo puedo detectar la existencia de una tabla de SQL en Java?] (Http://stackoverflow.com/questions/927807/how-can-i-detect-a-sql-tables-existence -in-java) – finnw

+0

Sea más específico en su pregunta. –

Respuesta

57

Usted puede usar los metadatos disponibles:

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

Ver here para más detalles. Tenga en cuenta también las advertencias en the JavaDoc.

+0

¡¡¡Gracias !!!!!! – Dmitry

+8

Está solicitando todas las tablas del servidor y luego navegando por esos nombres localmente. Eso no es muy eficiente si solo quieres comprobar si existe la tabla 'X'. ¡¡Quisiera usar el tercer argumento para el método 'getTables()'! (en lugar de utilizar 'nulo' como lo hace) – peterh

+0

@ nolan6000 - anotado y modificado. 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

Asegúrese de utilizar nombres de tabla que no estén usando caracteres de patrón como guiones bajos, como "employee_reports". Me han atrapado situaciones como esta ya que algunas implementaciones de metadatos usan patrones de coincidencia. Lo mejor es comprobar el conjunto de resultados con una simple declaración table.equals ("employee_reports") en su if – Constantin

+0

El mismo código también funciona para jgres de Postgres. Gracias. – Ankur

6

Adición al post de Gaby, mis getTables JDBC() para Oracle 10g requiere que los tapones para trabajar:

"employee" -> "EMPLOYEE"

de lo contrario habría obtener una excepción:

java. sql.SqlExcepcion resultado agotado

(aunque "empleado" está en el esquema)

5

No encuentro ninguna de las soluciones presentadas aquí para que esté completamente completa, así que agregaré la mía. Nada nuevo aquí. Puede unir esto de las otras soluciones presentadas más varios comentarios.

Hay por lo menos dos cosas que tendrá que asegurarse de que:

  1. asegurarse de que pase el nombre de la tabla a la getTables() method, en lugar de pasar un valor nulo. En el primer caso, permite que el servidor de base de datos filtre el resultado, en el segundo solicita una lista de todas las tablas del servidor y luego filtra la lista localmente. El primero es mucho más rápido si solo está buscando una sola tabla .

  2. Asegúrese de comprobar el nombre de la tabla del conjunto de resultados con una coincidencia igual a . El motivo es que el getTables() coincide con el patrón en la consulta de la tabla y el carácter _ es un comodín en SQL. Supongamos que está comprobando la existencia de una tabla llamada EMPLOYEE_SALARY. A continuación, obtendrá una coincidencia en EMPLOYEESSALARY también que no es lo que desea.

Ohh, y recuerde cerrar esos resultados. Desde Java 7, querrá usar un try-with-resources statement para eso.

Aquí es una solución completa:

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

Es posible que desee considerar lo que se pasa como parámetro types (cuarto parámetro) en su llamada getTables(). Normalmente me iría al null porque no desea restringirse. UNA VISTA es tan buena como una MESA, ¿verdad?En estos días, muchas bases de datos le permiten actualizar a través de una VISTA, por lo que restringirse a solo el tipo de TABLA no es, en la mayoría de los casos, el camino a seguir. YMMV.

+0

Puede necesitar cambiar 'tName.equals (tableName)' a 'tName.equals (tableName.toLowerCase())', no funcionaría si 'tableName' estuviera en mayúscula. – 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 
} 
Cuestiones relacionadas