首页 > 解决方案 > 仅当所有行都再次插入数据库表时,Android才会防止重复

问题描述

我正在开发一个计费 android 应用程序只有当表中的所有行再次重复时,我才需要防止重复。

我添加了一个回滚方法

rows = db.insertWithOnConflict("output_to_cloud4", null, cv, SQLiteDatabase.CONFLICT_REPLACE);

但仍然插入重复的细节

-这里分享我的插入方法

void Insert_OutputDetails_withTransation() {
    long rows = 0;

   db = openOrCreateDatabase("Student.db",OPEN_READWRITE, null);

    ContentValues cv = new ContentValues();
    db.beginTransaction();
    try {
        for (int i = 0; i < myMap.size(); i++) {
            float check_not_zeroValue = Float.parseFloat(myMap.get(PosUtils.PRODUCT_CODE.get(i)));
            if (!(check_not_zeroValue == 0.0f)) {

                try {

                    int time = (int) (System.currentTimeMillis());
                    Timestamp tsTemp = new Timestamp(time);
                    String ts =  tsTemp.toString();

                    Double round_amount = Double.valueOf(Rounded_Total_price_with_tax) - Double.valueOf(Total_price_with_tax);
                    cv.put("BILLNO", (LAST_BILL_NUMBER));
                    cv.put("BILLPREFIX", SALES_MAN_BILLPREFIX);
                    cv.put("BILLDATE", Date);
                    cv.put("saleman_code", SALES_MAN_CODE);
                    cv.put("DLYVEHICLE", SALES_MAN_DLYVANNO);
                    //"CUSTOMERCODE","PRODUCTCODE","QTY","RATE","GROSS",
                    cv.put("CUSTOMERCODE", CUSTOMERS_CODE_LIST.get(CUSTOMER_POSITION));
                    cv.put("PRODUCTCODE", PRODUCT_CODE.get(i));
                    cv.put("QTY", myMap.get(PosUtils.PRODUCT_CODE.get(i)));

                    cv.put("RATE", PRODUCT_RATE.get(i));
                    cv.put("GROSS", new DecimalFormat("0.00").format(item_price));

                    //"CGST","CGSTAMT","SGSTP","SGSTAMT","CESSP",
                    cv.put("CGST", PRODUCT_CGSTP.get(i));
                    cv.put("CGSTAMT", new DecimalFormat("0.00").format(amount_cgst));

                    cv.put("SGSTP", PRODUCT_SGSTP.get(i));
                    cv.put("SGSTAMT", new DecimalFormat("0.00").format(amount_sgst));

                    cv.put("CESSP", PRODUCT_CESSP.get(i));
                    //"CESSAMT","SCESSP","SCCAMT","ROUND","BTOTAL","
                    cv.put("CESSAMT", new DecimalFormat("0.00").format(amount_cseep));

                    cv.put("SCESSP", PRODUCT_SCESSP.get(i));
                    cv.put("SCCAMT", new DecimalFormat("0.00").format(amount_scessp));


                    cv.put("BTOTAL", new DecimalFormat("0.00").format(Rounded_Total_price_with_tax));
                    cv.put("ROUND", new DecimalFormat("0.00").format(round_amount));
                    cv.put("BILL_STATUS", "1");

                rows = db.insertWithOnConflict("output_to_cloud4", null, cv, SQLiteDatabase.CONFLICT_REPLACE);
              } catch (Exception in) {
                    in.getMessage();
                }
            }
        }
        db.setTransactionSuccessful();


    } catch (Exception e) {
        e.getMessage();
    } finally {
        db.endTransaction();
    }

}

我的数据库甲

     db.execSQL("CREATE  TABLE IF NOT EXISTS output_to_cloud3(" +
                "BILLNO TEXT,BILLPREFIX TEXT,BILLDATE TEXT,saleman_code TEXT,DLYVEHICLE TEXT," +
                "CUSTOMERCODE TEXT,PRODUCTCODE TEXT,QTY TEXT,RATE TEXT,GROSS TEXT," +
                "CGST TEXT,CGSTAMT TEXT,SGSTP TEXT,SGSTAMT TEXT,CESSP TEXT," +
                "CESSAMT TEXT,SCESSP TEXT,SCCAMT TEXT,ROUND TEXT,BTOTAL TEXT,BILL_STATUS TEXT,TIME_IN TEXT)");

如果有人在帮助我之前遇到这个问题......

标签: androidandroid-sqlite

解决方案


我相信你的问题是你期望重复被自动拒绝。

情况并非如此,您必须定义 CONSTRAINTS 除非它们是隐含的(例如,主索引暗示一个 UNIQUE 约束),而这些都不是。

最简单的解决方法,虽然可能不是最有效的,但要满足您的标准,我需要防止重复,只有当表中的所有行再次重复时。将基于具有 UNIQUE 约束的所有行创建一个索引,因此您可以使用:-

CREATE UNIQUE INDEX IF NOT EXISTS stop_dupplicates ON output_to_cloud4 (
    BILLNO,
    BILLPREFIX,
    BILLDATE,
    saleman_code,
    DLYVEHICLE,
    CUSTOMERCODE,
    PRODUCTCODE,
    QTY,
    RATE,
    GROSS,
    CGST,
    CGSTAMT,
    SGSTP,
    SGSTAMT,
    CESSP,
    CESSAMT,
    SCESSP,
    SCCAMT,
    ROUND,
    BTOTAL,
    BILL_STATUS,
    TIME_IN
);

insertWithOnConflict与其一起使用该方法,不如 SQLiteDatabase.CONFLICT_REPLACE只使用insert等同于的方法INSERT OR IGNORE .......,因此如果遇到重复项,则 INSERT 将被忽略(未插入)并继续处理,而不是用完全相同的数据替换(更新)一行.

示例/测试

基于列的子集,为方便起见,以下演示了上述内容:-

创建 output_to_cloud3 表:-

CREATE TABLE IF NOT EXISTS output_to_cloud3(
    BILLNO TEXT,
    BILLPREFIX TEXT,
    BILLDATE TEXT,
    TIME_IN TEXT
);

创建索引以停止插入重复项(所有行)

CREATE UNIQUE INDEX IF NOT EXISTS stop_dupplicates ON output_to_cloud3 (
    BILLNO,
    BILLPREFIX,
    BILLDATE,
    TIME_IN
);

插入一些数据:-

INSERT INTO output_to_cloud3
    VALUES
        ('A','B','C','D'),
        ('E','F','G','H'),
        ('I','J','K','L'),
        ('M','N','O','P'),
        ('Q','R','S','T')
;

该表现在将是:-

在此处输入图像描述

尝试 1 - 使用 INSERT 添加重复项。

  • 这相当于使用该 insertOrThrow方法)

:-

INSERT INTO output_to_cloud3
    VALUES
        ('A','B','C','D'),
        ('E','F','G','H'),
        ('I','J','K','L'),
        ('M','N','O','P'),
        ('Q','R','S','T')
;

尝试第一次插入时会抛出异常并且不会插入任何内容。

尝试 2 - 使用 INSERT OR REPLACE 添加重复项

  • 这相当于使用insertWithOnConflictwith SQLiteDatabase.CONFLICT_REPLACE

:-

INSERT OR REPLACE INTO output_to_cloud3
    VALUES
        ('A','B','C','D'),
        ('E','F','G','H'),
        ('I','J','K','L'),
        ('M','N','O','P'),
        ('Q','R','S','T')
;

然后不会引发异常,不会添加任何行,但是所有行都会更新,但表实际上没有改变。

尝试 3 - 使用 INSERT OR IGNORE 添加重复项

  • 这相当于使用该insert方法。

:-

INSERT OR IGNORE INTO output_to_cloud3
    VALUES
        ('A','B','C','D'),
        ('E','F','G','H'),
        ('I','J','K','L'),
        ('M','N','O','P'),
        ('Q','R','S','T')
;

然后不会引发异常,不会添加任何行,表没有变化。

尝试 4 - 使用 INSERT 添加非重复项和重复项

  • 这再次等同于使用该 insertOrThrow方法。

:-

INSERT INTO output_to_cloud3
    VALUES
        ('U','V','W','X'), -- New non-duplicate row
        ('A','B','C','D'),
        ('E','F','G','H'),
        ('I','J','K','L'),
        ('M','N','O','P'),
        ('Z','AA','AB','AC'), -- New non-duplicate row
        ('Q','R','S','T'),
        ('AD','AE','AF','AG') -- New non-dupliate row

;

然后抛出异常(由于它是单个语句,表将保持不变。)如果是单独的插入,则将插入第一行,然后第二行将导致异常。

尝试 5 - 使用 INSERT OR REPLACE 添加非重复项和重复项

  • 同样,这相当于使用该 insertWithOnConflict方法以及SQLiteDatabase.CONFLICT_REPLACE.

:-

INSERT OR REPLACE INTO output_to_cloud3
    VALUES
        ('U','V','W','X'), -- New non-duplicate row
        ('A','B','C','D'),
        ('E','F','G','H'),
        ('I','J','K','L'),
        ('M','N','O','P'),
        ('Z','AA','AB','AC'), -- New non-duplicate row
        ('Q','R','S','T'),
        ('AD','AE','AF','AG') -- New non-dupliate row

; 

这将插入非重复项并替换重复项(实际上使它们保持不变),结果表如下。

尝试 6 - 使用 INSERT OR IGNORE 添加非重复项和重复项

  • 这再次等同于使用该insert方法。

:-

INSERT OR REPLACE INTO output_to_cloud3
    VALUES
        ('U','V','W','X'), -- New non-duplicate row
        ('A','B','C','D'),
        ('E','F','G','H'),
        ('I','J','K','L'),
        ('M','N','O','P'),
        ('Z','AA','AB','AC'), -- New non-duplicate row
        ('Q','R','S','T'),
        ('AD','AE','AF','AG') -- New non-dupliate row

;

最终结果将与尝试 5 相同,即:-

在此处输入图像描述


推荐阅读