2010-05-31 56 views
67

Tôi có ứng dụng dành cho máy tính để bàn có cơ sở dữ liệu được nhúng trong đó hay không. Khi tôi thực hiện chương trình của mình, tôi cần phải kiểm tra xem bảng cụ thể đó có tồn tại không, hoặc tạo nó nếu không.Kiểm tra xem bảng có tồn tại

Cho một đối tượng kết nối có tên là conn cho cơ sở dữ liệu của tôi, làm cách nào tôi có thể kiểm tra điều này?

+4

bản sao có thể có của [Làm thế nào tôi có thể phát hiện sự tồn tại của bảng SQL trong Java?] (Http://stackoverflow.com/questions/927807/how-can-i-detect-a-sql-tables-existence -in-java) – finnw

+0

Hãy cụ thể hơn trong câu hỏi của bạn. –

Trả lời

57

Bạn có thể sử dụng dữ liệu meta có sẵn:

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

Xem here để biết thêm chi tiết. Cũng lưu ý rằng hãy cẩn thận trong the JavaDoc.

+0

Cảm ơn bạn !!!!!! – Dmitry

+8

Bạn đang yêu cầu tất cả các bảng từ máy chủ và sau đó duyệt qua các tên đó một cách cục bộ. Điều đó không hiệu quả lắm nếu bạn chỉ muốn kiểm tra xem bảng 'X' có tồn tại hay không. Bạn sẽ muốn sử dụng đối số thứ 3 cho phương thức 'getTables()' !!! (thay vì sử dụng 'null' như bạn làm) – peterh

+0

@ nolan6000 - được lưu ý và sửa đổi. 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

Đảm bảo rằng khi bạn sử dụng các tên bảng mà nó không sử dụng các ký tự mẫu như gạch dưới, chẳng hạn như "employee_reports". Tôi đã bị bắt bởi các tình huống như thế này khi một số triển khai siêu dữ liệu sử dụng tính năng khớp mẫu. Tốt nhất là hãy kiểm tra lại tập hợp kết quả bằng câu lệnh table.equals đơn giản ("employee_reports") trong if – Constantin

+0

Cùng một mã hoạt động cho postgres jdbc too.Thanks. – Ankur

6

Thêm bài Gaby của, getTables jdbc của tôi() cho Oracle 10g yêu cầu tất cả mũ để làm việc:

"employee" -> "EMPLOYEE"

Nếu không tôi sẽ nhận được một ngoại lệ:

java. sql.SqlExcepcion resultset cạn kiệt

(mặc dù "nhân viên" có trong lược đồ)

5

Tôi thực sự không tìm thấy bất kỳ giải pháp nào được trình bày ở đây để hoàn thành đầy đủ vì vậy tôi sẽ thêm của riêng mình. Không có gì mới ở đây. Bạn có thể ghép chúng lại với nhau từ các giải pháp được trình bày khác cùng với các nhận xét khác nhau.

Có ít nhất hai điều bạn sẽ phải chắc chắn rằng:

  1. Hãy chắc chắn rằng bạn vượt qua các tên bảng vào getTables() method, chứ không phải đi qua một giá trị null. Trong trường hợp đầu tiên bạn để máy chủ cơ sở dữ liệu lọc kết quả cho bạn, trong lần thứ hai bạn yêu cầu danh sách tất cả bảng từ máy chủ và sau đó lọc danh sách tại địa phương. Trước đây là nhanh hơn nhiều nếu bạn chỉ tìm kiếm một bảng đơn .

  2. Đảm bảo kiểm tra tên bảng từ resultset bằng kết quả trùng khớp là . Lý do là số getTables() khớp với mẫu trên truy vấn cho bảng và ký tự _ là ký tự đại diện trong SQL. Giả sử bạn đang kiểm tra sự tồn tại của một bảng có tên là EMPLOYEE_SALARY. Sau đó, bạn sẽ nhận được một trận đấu trên EMPLOYEESSALARY quá mà không phải là những gì bạn muốn.

Ồ, và nhớ đóng những bộ kết quả đó. Kể từ Java 7, bạn sẽ muốn sử dụng một try-with-resources statement cho điều đó.

Dưới đây là một giải pháp hoàn chỉnh:

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

Bạn có thể muốn xem xét những gì bạn vượt qua như types tham số (tham số thứ 4) trên getTables() cuộc gọi của bạn. Thông thường tôi sẽ rời khỏi số null vì bạn không muốn giới hạn bản thân. VIEW là tốt như một bảng, phải không?Những ngày này nhiều cơ sở dữ liệu cho phép bạn cập nhật thông qua VIEW để hạn chế bản thân đối với chỉ loại TABLE trong hầu hết các trường hợp không phải là cách để đi. YMMV.

+0

Bạn có thể cần phải thay đổi 'tName.equals (tableName)' thành 'tName.equals (tableName.toLowerCase())', nó sẽ không hoạt động nếu 'tableName' là chữ hoa. – 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 
} 
Các vấn đề liên quan