2014-07-08 222 views
0

我想從csv文件添加數據到Android上的SQLite數據庫。Android的SQLite插入問題

我的CSV文件中的數據看起來像這樣

SID,Attended,Serial,Time,Title,Forenames,Last name,Parking,How many people will be in your  party (including yourself)?,Any access requirements?,Access requirements,Timetable 
9290,,0000000092906,2014-04-07 18:44:59,Miss,foo1,foo1,,2,No,,fooo 
9291,,0000000092907,2014-04-08 18:44:59,Miss,foo2,foo2,,2,No,,fooo 
9292,,0000000092908,2014-04-07 18:44:59,Miss,foo3,foo3,,2,No,,fooo 

我創建了一個DatabaseHelper將其導入:

public void importFromCSV(String filename) 
{ 
    //deleteTable(); 
    SQLiteDatabase db = this.getReadableDatabase(); 
    String next[] = {}; 

    try { 
     db.beginTransaction(); 
     CSVReader reader = new CSVReader(new FileReader(filename)); 
     reader.readNext(); 
     for(;;) { 
      next = reader.readNext(); 
      if(next != null) { 
       this.addPerson(new Person(Long.parseLong(next[0]), 
         next[1], 
         Long.parseLong(next[2]), 
         next[3], 
         next[4], 
         next[5], 
         next[6], 
         next[7], 
         Integer.parseInt(next[8]), 
         next[9], 
         next[10], 
         next[11])); 
      } else { 
       break; 
      } 
     } 
     reader.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    finally { 
     db.endTransaction(); 
    } 

} 

但是,當我嘗試做一個選擇在我的數據庫,我得到了一個錯誤:CursorIndexOutOfBoundsException:索引0請求,大小爲0. 我做了一些研究,發現這個錯誤是因爲空的遊標。

這裏是我的getPerson功能:

public Person getPerson(long sid){ 

    // 1. get reference to readable DB 
    SQLiteDatabase db = this.getReadableDatabase(); 

    // 2. build query 
    Cursor cursor = 
      db.query(TABLE_PERSONS, // a. table 
      COLUMNS, // b. column names 
      " sid = ?", // c. selections 
      new String[] { String.valueOf(sid) }, // d. selections args 
      null, // e. group by 
      null, // f. having 
      null, // g. order by 
      null); // h. limit 

    // 3. if we got results get the first one 
    if (cursor != null) { 
     cursor.moveToFirst(); 
    } 

    // 4. build pers object 
    Person pers = new Person(); 

    pers.setSid(Long.parseLong(cursor.getString(0))); 
    pers.setAttended(cursor.getString(1)); 
    pers.setSerial(Long.parseLong(cursor.getString(2))); 
    pers.setTime(cursor.getString(3)); 
    pers.setTitle(cursor.getString(4)); 
    pers.setForename(cursor.getString(5)); 
    pers.setLastname(cursor.getString(6)); 
    pers.setParking(cursor.getString(7)); 
    pers.setNumberpeople(Integer.parseInt(cursor.getString(8))); 
    pers.setAccessreqornot(cursor.getString(9)); 
    pers.setAccessreq(cursor.getString(10)); 
    pers.setTimetable(cursor.getString(11)); 

    Log.d("getPerson()", pers.toString()); 

    // 5. return pers 
    return pers; 
} 

我認爲這個問題是由於()調用importFromCsv我addPerson的功能。 我的日誌在addPerson函數的開始處會返回正確的結果,但我認爲db.insert運行不正常。但我在這方面沒有任何錯誤。

我addPerson的功能:

public void addPerson(Person pers){ 
    Log.d("addPerson", pers.toString()); 
    // 1. get reference to writable DB 
    SQLiteDatabase db = this.getWritableDatabase(); 

    // 2. create ContentValues to add key "column"/value 
    ContentValues values = new ContentValues(); 
    values.put(SID, pers.getSid()); 
    values.put(ATTENDED, pers.getAttended()); 
    values.put(SERIAL, pers.getSerial()); 
    values.put(TIME, pers.getTime()); 
    values.put(TITLE, pers.getTitle()); 
    values.put(FORENAME, pers.getForename()); 
    values.put(LASTNAME, pers.getLastname()); 
    values.put(PARKING, pers.getParking()); 
    values.put(NUMBERPEOPLE, pers.getNumberpeople()); 
    values.put(ACCESSREQORNOT, pers.getAccessreqornot()); 
    values.put(ACCESSREQ, pers.getAccessreq()); 
    values.put(TIMETABLE, pers.getTimetable()); 

    // 3. insert 
    db.insert(TABLE_PERSONS, // table 
      null, //nullColumnHack 
      values); // key/value -> keys = column names/ values = column values 
} 

感謝您的閱讀時間,如果有人有任何想法,我將非常感激。

編輯:堆棧跟蹤:

07-08 12:01:57.755: D/addPerson(10828): Person [sid=9290, attended=, serial=92906, time=2014-04-07 18:44:59, title=Miss, forename=Ladina, lastname=Clement, parking=, numberpeople=2, accessreqornot=No, accessreq=, timetable=Fine] 
07-08 12:01:57.755: D/addPerson(10828): Person [sid=9291, attended=, serial=92907, time=2014-04-08 18:44:59, title=Miss, forename=Ladina2, lastname=Clement2, parking=, numberpeople=2, accessreqornot=No, accessreq=, timetable=Fine] 
07-08 12:01:57.763: D/addPerson(10828): Person [sid=9292, attended=, serial=92908, time=2014-04-07 18:44:59, title=Miss, forename=Ladina3, lastname=Clement3, parking=, numberpeople=2, accessreqornot=No, accessreq=, timetable=Fine] 
07-08 12:01:59.193: D/ViewRootImpl(10828): ViewRoot TouchDown(Absolute) DOWN (357 , 189) 
07-08 12:01:59.247: D/getAllPersons()(10828): [] 
+0

你有檢查,如果有一些數據保存在哪裏?插入東西后。 – MAOL

+0

儘管沒有意識到程序的複雜性,但更簡單的方法是[this](https://github.com/jgilfelt/android-sqlite-asset-helper) – Skynet

+0

請發佈完整的堆棧跟蹤。 – Simas

回答

2

改變這一行:

if (cursor != null) { 
    cursor.moveToFirst(); 
} 

if (!cursor.moveToFirst()) { 
    // do something when there are no results 
} 

光標上的空檢查是多餘的。您可以通過執行cursor.moveToFirst()來檢查遊標是否爲空。如果它返回false,你應該像以後一樣避免在光標上執行進一步的命令,例如, cursor.getString(0)。

+0

爲什麼不使用其他條件? (cursor!= null && cursor.moveToFirst())? – Skynet

+0

@ByzantineFailure無需檢查空遊標。如果沒有查詢結果,那麼爲什麼使用else可以調用並附上一個海量代碼塊。 – Simas

+0

我對演出效果並不確定,但對此進行研究會很有趣。將更新並保持張貼在這裏。 – Skynet

1

我的數據是這樣的:

25-07-14 12:00,15,52,16,50,42,58,63,62,52 
22-06-14 14:00,15,52,16,50,42,58,63,62,52 
12-09-14 19:00,45,51,16,50,42,58,13,34,52 
02-02-14 16:00,15,52,16,50,42,58,63,62,52 
01-05-14 12:00,15,52,16,50,42,58,63,62,52 

我已閱讀,這樣的數據,你可以找到一次。在我檢查的文件路徑中,csv文件不是。

FilePath = data.getData().getPath(); 
       if(FilePath.substring(FilePath.length()-4).endsWith(".csv")) 

而且代碼是在這裏

private void readcsvfile() { 

    if(FilePath.length()>4) 
    { 
    dataGridTable = new DgaDataGridTable(context); 
    equipmentTable = new EquipmentTable(context); 

    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(FilePath))); 

     String line; 

     while ((line=reader.readLine())!=null) 
     { 
      info = new DgaDataGridInfo(); 
      String[] rowData = line.split(","); 

      if(rowData[0].length()!=0&&rowData[1].length()!=0&&rowData[2].length()!=0&&rowData[3].length()!=0&&rowData[4].length()!=0&&rowData[5].length()!=0&&rowData[6].length()!=0&&rowData[7].length()!=0&&rowData[8].length()!=0&&rowData[9].length()!=0) 
      { 
       info.setDateadded(rowData[0]); 
       info.setH2(Integer.parseInt(rowData[1])); 
       info.setCh4(Integer.parseInt(rowData[2])); 
       info.setC2h2(Integer.parseInt(rowData[3])); 
       info.setC2h4(Integer.parseInt(rowData[4])); 
       info.setC2h6(Integer.parseInt(rowData[5])); 
       info.setCo(Integer.parseInt(rowData[6])); 
       info.setCo2(Integer.parseInt(rowData[7])); 
       info.setO2(Integer.parseInt(rowData[8])); 
       info.setN2(Integer.parseInt(rowData[9])); 
       info.setTdcg(Integer.parseInt(rowData[1])+Integer.parseInt(rowData[2])+Integer.parseInt(rowData[5])+Integer.parseInt(rowData[4])+Integer.parseInt(rowData[3])+Integer.parseInt(rowData[6])); 
       equipmentname = equipment_spinner.getSelectedItem().toString(); 

       info.setEquipid(equipmentTable.getEquipmentId(equipmentname)); 

       dataGridTable.insertRecord(info); 

       Toast.makeText(this, "Dga Records Succesfully Added", Toast.LENGTH_LONG).show(); 
       loadAllDgaRecords(); 

      } 
      else 
      { 
       showAlertDialog(); 
      } 

     } 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 
    else 
     Toast.makeText(this, "Please choose csv file", Toast.LENGTH_LONG).show(); 

} 

感謝