Проверьте, существует ли таблица

У меня есть настольное приложение с встроенной в него базой данных. Когда я выполняю свою программу, мне нужно проверить, существует ли определенная таблица или создать ее, если нет.

Учитывая объект Connection с именем conn для моей базы данных, как я могу проверить это?

Ответ 1

Вы можете использовать доступные метаданные:

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

Подробнее см. здесь. Также обратите внимание на оговорки в JavaDoc.

Ответ 2

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

Добавляя к сообщению Gaby, my jdbc getTables() для Oracle 10g требует, чтобы все кепки работали:

"employee" -> "EMPLOYEE"

В противном случае я получаю исключение:

java.sql.SqlExcepcion исчерпаны результаты

(даже если "сотрудник" находится в схеме)

Ответ 4

Я не нахожу, чтобы какое-либо из представленных здесь решений было полностью полным, поэтому я добавлю свои собственные. Здесь ничего нового. Вы можете сшить это вместе с другими представленными решениями и различными комментариями.

Есть, по крайней мере, две вещи, которые вы должны убедиться:

  • Убедитесь, что вы передали имя таблицы в метод getTables(), вместо передачи нулевого значения. В первом случае вы сервер базы данных фильтрует результат для вас, во втором запросе список всех таблиц с сервера, а затем фильтр списка на местном уровне. Первый намного быстрее, если вы ищете только одиночная таблица.

  • Обязательно проверьте имя таблицы из набора результатов с равными совпадение. Причина в том, что getTables() сопоставляет шаблон по запрос для таблицы и символ _ является подстановочным знаком в SQL. Предположим, вы проверяете наличие таблицы с именем EMPLOYEE_SALARY. Затем вы получите совпадение на EMPLOYEESSALARY который не является тем, что вы хотите.

Ой, и не забудьте закрыть эти результирующие множества. Начиная с Java 7 вы бы хотели использовать инструкцию try-with-resources.

Здесь полное решение:

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

Вы можете рассмотреть, что вы передаете в качестве параметра types (4-й параметр) в своем вызове getTables(). Обычно я просто уезжаю в null, потому что вы не хотите ограничивать себя. ПРОСМОТР так же хорош, как ТАБЛИЦА, не так ли? В наши дни многие базы данных позволяют вам обновлять через VIEW, поэтому ограничивая себя только типом TABLE, в большинстве случаев это не путь. YMMV.

Ответ 5

    /**
 * 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
}