【问题标题】:Android sqlite insert issueAndroid sqlite插入问题
【发布时间】:2014-07-08 10:45:40
【问题描述】:

我正在尝试将数据从 csv 文件添加到 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();
    }

}

但是当我尝试在我的数据库上执行 SELECT 时,我收到了一个错误: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): []

【问题讨论】:

  • 您是否检查过是否存储了一些数据?插入东西后。
  • 虽然不知道程序的复杂性,但更简单的方法是this
  • 请发布完整的堆栈跟踪。
  • 您只需从内部文件夹复制您的数据库——您不需要根设备。检查better explanation here
  • 您应该打印db.insert(TABLE_PERSONS... 调用的输出,因为返回码告诉您“新插入行的行 ID,如果发生错误,则为 -1”

标签: android sqlite csv


【解决方案1】:

改变这一行:

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

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

对游标的空检查是多余的。您可以通过执行 cursor.moveToFirst() 来检查光标是否为空。如果它返回 false 你应该阻止在光标上执行进一步的命令,就像你稍后做的那样,例如cursor.getString(0).

【讨论】:

  • 为什么不使用 else 条件? (cursor != null && cursor.moveToFirst())?
  • @ByzantineFailure 无需检查空游标。以及为什么在没有查询结果的情况下可以调用return时使用else条件并附上大量代码块。
  • 我不确定性能影响,但对此进行研究会很有趣。将在此处更新并继续发布。
  • 我试着改了,“没有结果的时候的东西”没有触发,所以它必须是别的东西。
【解决方案2】:

我的数据是这样的:

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();

}

谢谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多