android - 仅当所有行都再次插入数据库表时,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)");
如果有人在帮助我之前遇到这个问题......
解决方案
我相信你的问题是你期望重复被自动拒绝。
情况并非如此,您必须定义 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 添加重复项
- 这相当于使用
insertWithOnConflict
withSQLiteDatabase.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 相同,即:-
推荐阅读
- javascript - 如何遍历一个数组并获取id对应的名称并将结果分配给另一个数组
- vba - 我无法更新表字段,错误 3027(无法更新。数据库对象是只读的)不断弹出
- amazon-cognito - 使用 Cognito IDToken 保护 Cloudfront
- c# - 如何在事件处理程序中停止执行数据获取和显示方法
- css - 仅在 WooCommerce 单个产品页面上增加产品价格字体大小
- python - 是否可以通过与后一个列表交互来找到放入另一个列表中的列表的原始名称?
- plsql - 插入过程 - 检查主表中是否存在外键
- android - Lollipop 设置远程描述错误:启用 BUNDLE 时必须启用 rtcp-mux
- php - 使用 JQuery AJAX 和 php 获取数据到 mysql 数据库
- reactjs - 代码优化。一个函数而不是几行重复的代码