我对一个看似简单的sqlite问题感到非常沮丧。我在客户端有一个包含3条记录的表。收集这些记录并前往服务器进行插入后,我有一个清理功能,可以搜索服务器上的新记录,并在客户端上运行删除,准备将其添加回服务器特定的ID。我不一定喜欢删除,当更新时更好,但是,我写的基于网络的应用程序可以从多个iPad设备和用户访问,我们需要一种方法来保持客户端数据与服务器同步。我已经尝试了各种方法,一旦考虑了离线可能性,就会出现问题。
所以,代码。我收集id并执行删除(multiple_records_deleted是一个布尔值,用于在删除语句完成时指示setTimeout。)
ids = ids.substring(0,ids.length-1);
db.transaction(function (tx) {
tx.executeSql("DELETE FROM " + table + " WHERE id IN (" + ids + ")", [], function (tx, results) {
console.log("DELETE FROM " + table + " WHERE id IN (" + ids + ")");
multiple_records_deleted = true;
});
});
然后,目标是插入可能相同或不相同的新记录(有关键和时间戳字段以及对仅有服务器具有的应用程序至关重要的其他复杂关系。)
sqlInserts[0] = "sql to insert first record";
sqlInserts[1] = "sql to insert second record";
sqlInserts[2] = "sql to insert third record";
function insertMultipleRecords() {
for (var x = 0; x < sqlInserts.length - 1; x++) {
db.transaction(function (tx) {
tx.executeSql(sqlInserts[x],[]);
}, badCB, goodCB);
}
}
我的问题的长期和不足之处在于,每次运行此代码时,只会执行数组中的最后一项。我已经尝试了几乎所有我能想到的db.transaction变体。用过的计时器。使用其他回调。但无济于事。奇怪的是,我在应用程序的另一部分运行了一个类似的代码块,它运行正常。
任何想法为什么它只是数组中成功运行的最后一项,而其余的似乎无处可去?
谢谢.. 罗宾
编辑:
以下是代码的后续内容。
for (var rec in response.table.records.record) {
db.transaction(function (tx) {
console.log("DELETE FROM " + table + " WHERE id = " + response.table.records.record[rec].f[record_idnumber_fld_ctr]);
tx.executeSql("DELETE FROM " + table + " WHERE id = " + response.table.records.record[rec].f[record_idnumber_fld_ctr], [], function (tx, results) {
// then insert
fld_ctr = 0;
setTableColumns("table_columns",table); // ensure we are using the right table
sql = "INSERT INTO " + table + " (";
for (x = 0; x < table_columns.length; x++) {
sql += table_columns[x] + ",";
}
sql = sql.substring(0,sql.length-1) + ") ";
sql += "SELECT ";
for (var fld in response.table.fields.field) {
var obj = response.table.fields.field[fld];
for (var prop in obj) {
if (prop === "@attributes") { // cast the data
sql += formatData(obj[prop].field_type,response.table.records.record[rec].f[fld_ctr]) + ",";
}
}
fld_ctr++;
}
// special cases for certain tables
if (table == "orders") {
if (response.table.records.record[rec].f[43] != "") sql += formatData("string","YES") + ","; // siggy
else sql += formatData("string","") + ",";
}
if (table == "pictures") {
sql += formatData("string","") + ","; // datauri
}
sql += "'SYNCED',";
sql += "'NO',";
sql += formatData("integer",response.table.records.record[rec].f[record_idnumber_fld_ctr]) + ",";
sql += "'VALID',";
sql += "'NO ERRORS'";
console.log(sql);
db.transaction(insertRecords(sql), errorHandler);
});
});
}
我从服务器运行记录的结果集。对于每一个,我尝试从表中删除一个键是相同的。两个console.logs显示相同的措辞全部3次...匹配数组中的最后一个。我确定这是一个关闭问题,只是不确定如何攻击它。
答案 0 :(得分:0)
这是一个经典问题,变量只是一个参考,而不是及时的快照。因此,在执行回调时,x的值已经更改。因此,您需要将函数拉出到单独的函数中或使用闭包。
function runTrans (x) {
db.transaction(function (tx) {
tx.executeSql(sqlInserts[x],[]);
}, badCB, goodCB);
}
function insertMultipleRecords() {
for (var x = 0; x < sqlInserts.length - 1; x++) {
runTrans(x);
}
}
或
function insertMultipleRecords() {
for (var x = 0; x < sqlInserts.length - 1; x++) {
(function(x) {
db.transaction(function (tx) {
tx.executeSql(sqlInserts[x],[]);
}, badCB, goodCB);
}(x));
}
}