Sqlite真实数据无效(无法重现)

时间:2017-09-11 12:41:53

标签: android sqlite android-sqlite

我有文本文件,我将其转换为带有事务的插入查询(千条记录)。

我使用的插入查询是这样的事务包装。

public static void bulkInsert(DatabaseWrapper db, String tableName, String[] columns, String[][] values){
    StringBuilder stringBuilder = new StringBuilder();
    int index = 0;
    String head = "INSERT OR REPLACE INTO " + tableName + " (" + TextUtils.join(",", columns) + ") VALUES ";
    while (index < values.length) {
        stringBuilder.setLength(0);
        stringBuilder.append(head);
        for (int i = 0; i < 500; i++) {
            if (index < values.length) {
                if (i != 0) stringBuilder.append(",");
                stringBuilder.append("(").append(TextUtils.join(",",values[index])).append(")");
            } else {
                break;
            }
            index++;
        }
        db.execSQL(stringBuilder.toString());
    }
}

然后我发现3964条记录中单个记录的真实价值从10.86变为1.95223612752995e-314,但其他记录看起来很好。 我不知道这里发生了什么。

Edited1

文本文件的示例是这样的

  

1004500803 KH1 001 P01 344 8850123136016 0000 0000010.86 00000 00000   0054 30082017080

     

1004500803 KH1 001 P01 345 8850123136023 0000 0000010.86 00000 00000   0055 30082017077

     

1004500803 KH1 001 P01 199 8850123123337 0001 0000007.24 00000 00000   0061 30082017081

     

1004500803 KH1 001 P01 032 8850123130410 0000 0000010.86 00000 00000   0065 30082017074

     

1004500803 KH1 001 P01 383 8850123135040 0001 0000010.86 00000 00000   0071 30082017074

文本数据的每个位置都在代码中修复,因此决定将列名和值转换为字符串数组

String[][] fileValues;
fileValues = PRS.getValueArrays();
public String[][] getValueArrays() {
        try {
            File file = new File(Constant.Path.MASTER_FILE_PATH, getFileName());
            List<String[]> list = new ArrayList<>();
            if (file.exists()) {
                BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "TIS-620"));
                String line;
                while ((line = br.readLine()) != null && !line.isEmpty() && !line.contains("EOF")) {
                    String[] valueArray = new String[fileIndex.length];
                    for (int i = 0; i < fileIndex.length - 1; i++) {
                        valueArray[i] = line.substring(fileIndex[i], fileIndex[i + 1]).trim();
                    }
                    valueArray[fileIndex.length - 1] = line.substring(fileIndex[fileIndex.length - 1], lineLength).trim();
                    list.add(valueArray);
                }
                br.close();
                String[][] valueList = new String[list.size()][];
                return list.toArray(valueList);
            }
        } catch (IOException | NullPointerException e) {
            e.printStackTrace();
        }
        return null;
    }

这是函数我将文本文件解析为字符串数组(可能有一些业务逻辑)

public static String[][] parsePrsFileToPresaleValues(String[][] fileValue) {
    String[][] result = new String[fileValue.length][];
    sumRawPrice = 0;
    for (int i = 0; i < fileValue.length; i++) {
        String[] fromFile = fileValue[i];
        double price = Double.parseDouble(fromFile[7]);
        sumRawPrice += price;
        result[i] = getPresaleValue(
                fromFile[0],
                fromFile[5],
                Integer.parseInt(fromFile[6]),
                fromFile[8].equals("00000") ? 9999 : fromFile[8].equals("99999") ? 0 : Integer.parseInt(fromFile[8]),
                fromFile[9].equals("99999") ? 9999 : fromFile[9].equals("00000") ? 0 : Integer.parseInt(fromFile[9]),
                price
        );
    }
    return result;
}

并像这样调用批量插入

public static void insertData(DatabaseWrapper db) {
    db.beginTransaction();
    DbUtil.bulkInsert(db, Presale.NAME, Presale.INSERT_COLUMN, Presale.parsePrsFileToPresaleValues(fileValues));
    db.setTransactionSuccessful();
    db.endTransaction();
}

这是插入语句字符串

的结果
INSERT OR REPLACE INTO price_methods (code,item_code,promotion_code,price,created_at,updated_at) VALUES ('KB0','8850123110108','000',24.67,1503503909093,1503503909093),('KB0','8850123110115','000',12.71,1503503909101,1503503909101)

Edited2

顺便说一下,它并不是一直发生的。 这个应用程序运行两年,并插入这样的数据,每天约10k记录,并在此之前正常工作

1 个答案:

答案 0 :(得分:0)

您的值的内部表示具有一些差异,因为它can't be represented exactly是二进制浮点数。如果你在double / float等之间进行转换,这尤其是一个问题。

您尚未发布所有代码,因此请务必先使用适合您用法的correct column type。还可以考虑在应用程序中使用BigDecimal来利用缩放等方法