2014-07-08 181 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(); 

} 

感谢