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


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

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

6 75

6 ответов:

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

  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.

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
}

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

"employee" -> "EMPLOYEE"

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

java.язык SQL.SqlExcepcion исчерпал resultset

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

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

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

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

  2. обязательно проверьте имя таблицы из результирующего набора с помощью equals спичка. Причина в том, что 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;
}

вы можете рассмотреть то, что вы передаете как (4-й параметр) на getTables() звонок. Обычно я бы просто ушел в null потому что ты не хотите ограничить себя. Вид так же хорош, как и стол, верно? В эти дни многие базы данных позволяют обновлять через представление, поэтому ограничение себя только типом таблицы в большинстве случаев не является способом. МММ.

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

при использовании jruby, вот фрагмент кода для возврата массива всех таблиц в БД.

require "rubygems"
require "jdbc/mysql"
Jdbc::MySQL.load_driver
require "java"

def get_database_tables(connection, db_name)
  md = connection.get_meta_data
  rs = md.get_tables(db_name, nil, '%',["TABLE"])

  tables = []
  count = 0
  while rs.next
    tables << rs.get_string(3)
  end #while
  return tables
end