2010-10-08 57 views
11

Trong mã bên dưới, pathToNonDatabase là đường dẫn đến tệp văn bản đơn giản, không phải là cơ sở dữ liệu sqlite thực. Tôi đã hy vọng cho sqlite3_open để phát hiện điều đó, nhưng không (db không phải là NULLresultSQLITE_OK). Vì vậy, làm thế nào để phát hiện rằng một tập tin không phải là một cơ sở dữ liệu sqlite hợp lệ?Cách để biết tệp cơ sở dữ liệu sqlite có hợp lệ hay không

sqlite3 *db = NULL; 
int result = sqlite3_open(pathToNonDatabase, &db); 

if((NULL==db) || (result!=SQLITE_OK)) { 
    // invalid database 
} 

Trả lời

12

sqlite mở cơ sở dữ liệu một cách uể oải. Chỉ cần làm một cái gì đó ngay lập tức sau khi mở mà đòi hỏi nó phải là một cơ sở dữ liệu.

Tốt nhất có thể là pragma schema_version;.

  • Điều này sẽ báo cáo 0 nếu cơ sở dữ liệu chưa được tạo (ví dụ: tệp trống). Trong trường hợp này, đó là công việc an toàn với (và chạy CREATE TABLE, v.v.)
  • Nếu cơ sở dữ liệu đã được tạo, nó sẽ trả lại bao nhiêu sửa đổi lược đồ đã trải qua. Giá trị này có thể không thú vị, nhưng đó không phải là 0.
  • Nếu tệp tồn tại và không phải là cơ sở dữ liệu (hoặc trống), bạn sẽ gặp lỗi.

Nếu muốn kiểm tra kỹ hơn, bạn có thể sử dụng pragma quick_check;. Đây là kiểm tra tính toàn vẹn trọng lượng nhẹ hơn, bỏ qua kiểm tra xem nội dung của các bảng có phù hợp với các chỉ mục hay không. Nó vẫn có thể rất chậm.

Tránh integrity_check. Nó không chỉ kiểm tra mọi trang, mà còn kiểm tra nội dung của các bảng so với các chỉ mục. Đây là băng hà tích cực trên một cơ sở dữ liệu lớn.

+1

"pragma schema_version;" ném "cơ sở dữ liệu bị khóa" lỗi đôi khi. Tôi sẽ cung cấp cho "pragma quick_check;" a try –

+1

Nếu cơ sở dữ liệu của bạn bị khóa, nó bị khóa. Mọi thứ sẽ thất bại. Hãy thử lại khi nó không bị khóa. :) –

+0

Bạn nói đúng. Mọi thứ đều thất bại khi cơ sở dữ liệu bị khóa. Ngay cả lựa chọn. Trong trường hợp của tôi, tôi muốn xác định xem tệp có phải là một cơ sở dữ liệu Sqlite3 hay không. Nếu tôi nhận được "cơ sở dữ liệu bị khóa" lỗi Tôi nghĩ rằng nó là an toàn để giả định tập tin là một cơ sở dữ liệu Sqlite3. –

2

Tôi nghĩ pragma integrity_check có thể làm điều đó.

+0

Được cảnh báo; điều này có thể rất chậm nếu cơ sở dữ liệu của bạn lớn. –

4

Đối với bất cứ ai cần phải làm điều này trong C# với System.Data.SQLite bạn có thể bắt đầu một giao dịch, và sau đó ngay lập tức cuộn nó lại như sau: -

private bool DatabaseIsValid(string filename) 
    { 
     using (SQLiteConnection db = new SQLiteConnection(@"Data Source=" + filename + ";FailIfMissing=True;")) 
     { 
      try 
      { 
       db.Open(); 
       using (var transaction = db.BeginTransaction()) 
       { 
        transaction.Rollback(); 
       } 
      } 
      catch (Exception ex) 
      { 
       log.Debug(ex.Message, ex); 
       return false; 
      } 
     } 
     return true; 
    } 

Nếu tập tin không phải là một cơ sở dữ liệu hợp lệ các sau SQLiteException được ném - tệp được mã hóa hoặc không phải là cơ sở dữ liệu (System.Data.SQLite.SQLiteErrorCode.NotADb). Nếu bạn không sử dụng cơ sở dữ liệu được mã hóa thì giải pháp này là đủ. (Chỉ có 'db.Open()' được yêu cầu cho phiên bản 1.0.81.0 của System.Data.SQLite nhưng khi tôi nâng cấp lên phiên bản 1.0.91.0 tôi phải chèn khối sử dụng bên trong để làm cho nó hoạt động).

Các vấn đề liên quan