2011-09-06 989 views
1

經過大量的搜索並在StackOverflow上閱讀有關SQLite的其他討論後,我找到你,但我絕對找不到解決我的問題的任何解釋,因此它是:SQLite問題「無法打開數據庫文件」

  • 上下文:
    我深化發展爲iPad至極的應用程序來處理一些「大」的數據,在多個場合。在其中之一中,我必須從.kml文件(谷歌的xml地理數據)中導入點座標到我的數據庫中,以便稍後用MKMapView重新使用它們,並且在需要顯示特定層。

  • 細節:
    進口的東西是很容易的:與文件打交道時,我只關心兩個表:

    • 一種含區的定義和詳細資料:暫時,作爲ID的integer和用於命名的text
    • 其中一個包含兩個用於座標存儲的real和一個用於瞭解哪個區域點屬於第一個表的integer
      只要讀取我的文件,我首先爲新區域創建一個條目,然後在第二個表格中插入點,並在第一個表格中創建最後一個區域的ID ...沒有什麼複雜的!

    但是......

  • 問題:
    運行正常一段時間後,我得到一個異常從SQLite的有著名的消息「無法打開數據庫文件」,然後將其我無法對數據庫做更多的事情。該例外可以在區域創建或點插入方法中隨機出現。

  • 我reflexions:
    考慮到這些文件中的無數個點,我懷疑內存或磁盤飽和,但其他部分的我的應用程序丟棄那些點(在我看來)。首先,內存:當發生異常時,應用程序使用大約10或12 MB的RAM。它看起來相當龐大,但是這是由於內存中加載了大約10MB的.kml文件,所以它是可以解釋的。而最重要的是,我的應用程序中的MKMapView事物處理地圖上方的大量高分辨率圖塊,因此導致內存峯值達到20甚至25MB,而不會使iPad崩潰。其次,磁盤:重置我的數據庫並只填充上述兩個表時,發生異常時的db文件大小總是大約2.2或2.5MB,但當我填充其他表時(我的應用程序的其他部分運行良好!)db文件大約是6或7MB,並且設備根本沒有抱怨。

  • 那又怎樣?!
    CPU憤怒和恐慌?我不這麼認爲,因爲我的數據庫的其他表格在同一個節點上沒有問題地填充......並且在模擬器中運行我的應用程序也崩潰了,而核心i7只是在嘲笑這項工作。
    SQLite不好用?我們走了!在我看來,這是唯一的解決方案!但是我真的無法理解這裏發生了什麼,因爲我按照我在其他應用程序的部分處理我的請求 - 重複我自己 - 像魅力一樣工作!

  • SQLite的細節:
    我有一個DB類,這是我使用,以免被包含在這個類創建/釋放的SqliteConnection對象的每個請求我做的,我所有的方法處理數據庫是一個單身當然,如果不知道它,我不會在其他地方玩這個連接。下面是這個類的有關方法:

    public void  saveZone(ObjZone zone) { //at this point, just creates an entry with a name and let sqlite give it a new id 
        lock (connection) { //SqliteConnection object 
         try { 
          openConnection(); 
          SqliteCommand cmd = connection.CreateCommand(); 
          cmd.CommandText = zone.id == 0 ? 
           "insert into ZONES (Z_NAME) values (" + format(zone.name) + ") ;" : 
           "update ZONES set Z_NAME = " + format(zone.name) + " where Z_ID = " + format(zone.id) + " ;"; 
          cmd.ExecuteNonQuery(); 
          if (zone.id == 0) { 
           cmd.CommandText = "select Z_ID from ZONES where ROWID = last_insert_rowid() ;"; 
           zone.id = uint.Parse(cmd.ExecuteScalar().ToString()); 
          } 
          cmd.Dispose(); 
         } 
         catch (Exception e) { 
          Log.failure("DB.saveZone(" + zone.ToString() + ") : [" + e.GetType().ToString() + "] - " + 
           e.Message + "\n" + e.StackTrace); //custom Console.WriteLine() method with some formating 
          throw e; 
         } 
         finally { 
          connection.Close(); 
         } 
        } 
    } 
    
    public void  setPointsForZone(List<CLLocationCoordinate2D> points, uint zone_id) { //registers points for a given zone 
        lock (connection) { 
         try { 
          openConnection(); 
          SqliteCommand cmd = connection.CreateCommand(); 
          cmd.CommandText = "delete from ZONESPOINTS where Z_ID = " + format(zone_id); 
          cmd.ExecuteNonQuery(); 
          foreach(CLLocationCoordinate2D point in points) { 
           cmd.CommandText = "insert into ZONESPOINTS values " + 
            "(" + format(zi_id) + ", " + format(point.Latitude.ToString().Replace(",", ".")) + ", " 
            + format(point.Longitude.ToString().Replace(",", ".")) + ");"; 
           cmd.ExecuteNonQuery(); 
           cmd.Dispose(); 
          } 
         } 
         catch (Exception e) { 
          Log.failure("DB.setPointsForZone(" + zone_id + ") : [" + e.GetType().ToString() + "] - " + e.Message); 
          throw e; 
         } 
         finally { 
          connection.Close(); 
         } 
        } 
    } 
    

    而且要盡我所能爲清楚,這裏有一些在上述兩個(因爲我用在最外鍵約束我用這個自定義openConnection()方法引用的方法我的表和級聯行爲是不是默認啓用的,但我需要他們):

    void openConnection() { 
        try { 
         connection.Open(); 
         SqliteCommand cmd = connection.CreateCommand(); 
         cmd.CommandText = "PRAGMA foreign_keys = ON"; 
         cmd.ExecuteNonQuery(); 
         cmd.Dispose(); 
        } 
        catch (Exception e) { 
         Log.failure("DB.openConnection() : [" + e.GetType().ToString() + "] - " + e.Message); 
         throw e; 
        } 
    } 
    
    public static string format(object o) { 
        return "'" + o.ToString().Replace("'", "''") + "'"; 
    } 
    

,遺憾的小說,我可能已經感謝您閱讀所有的東西,沒有?!無論如何,如果我錯過了可能有用的東西,請告訴我,我會盡快記錄下來。 我希望有人能夠幫助我,無論如何,先謝謝你!
(和我爲我可憐的frenchie的英語道歉)

編輯
我的問題是「解決」了!經過幾次調試,我沒有做出大的修改,但沒有成功,我將代碼放回到發佈它的狀態......現在它可以正常工作。但是,如果有人能夠給我一個可能發生的事情的解釋,我真的很感激!看起來像SQLite的行爲(在iPad上至少 - 從未在任何其他地方使用過)可能在某些時候很模糊...:/

+1

順便說一句,如果有人可以告訴我爲什麼地獄StackOverflow不會讓我開始我的帖子'你好'?我一直認爲禮貌是獲得問題答案的最佳方式! – psycho

+2

你嘗試過Bonjour嗎? – arunkumar

回答

2

我不會爲了這個而穿過我的手指,但我會嘗試兩件事:

  1. 如果可能的話,前處理的KML文件到第二SQLite數據庫,並使用該數據庫來在主數據庫(低存儲器/處理器要求思維)
  2. 事務在小批量導入的數據導入數據。

HTH

編輯:你可能已經檢查這一點,但無論如何:unable to open database

+0

已經選中,但是謝謝!你的第一個想法並不壞,但由於我要寫一個編輯,我「解決了」我的問題。 – psycho

+0

是的,這種「神聖干預」在我看來也是偶爾發生的,但當我想到生產環境時,這是最令人恐懼的事情。 –

+0

我同意這一點,這就是我所害怕的...但我沒有時間,所以讓我們祈禱! :/ – psycho

相關問題