#ios #database #html #web-sql
#iOS #База данных #HTML #web-sql
Вопрос:
В настоящее время у меня есть транзакция, которая пытается вставить данные в таблицу. Если данные уже есть в таблице, возникает ошибка с ошибкой ограничения, и выполняется выбор для получения идентификатора.
t2.executeSql('INSERT INTO books (book) VALUES (?);',
[record],
function (t2, r) { // SQL_successfulCallback
record = r.insertId;
},
function (t2, err) { // SQL_errorCallback
if (err.message !== 'constraint failed') { // insert failed because of other
// reason - fail transaction
console.log('Insert SQL error ' err.code ' - ' err.message '.');
return true;
} else { // insert failed because data was already in the table
t2.executeSql('SELECT bookID FROM books WHERE book=?',
[record],
function (t, r) { // SQL_successfulCallback
record = r.rows.item(0).classificationID;
},
function (t, err) { // SQL_errorCallback
console.log('Lookup SQL error ' err.code ' - ' err.message '.');
return true;
}
);
return false;
}
}
);
Я хочу ускорить транзакцию, поэтому подумал, что сначала посмотрю, были ли данные в таблице. Если это не так, вставьте его…
t2.executeSql('SELECT bookID FROM books WHERE book=?',
[record],
function (t2, r) { // SQL_successfulCallback
if (r.rows.length !== 0) {
record = r.rows.item(0).bookID;
} else {
t2.executeSql('INSERT INTO books (book) VALUES (?);',
[record],
function(t2, r){ // SQL_successfulCallbac
record = r.insertId;
},
function (t2, err) { // SQL_errorCallback
if (err.message !== 'constraint failed') { // insert failed because of other
// reason - fail transaction
console.log('Insert SQL error ' err.code ' - ' err.message '.');
return true;
} else { // insert failed because data was already in the table
return false;
}
}
);
}
},
function (t, err) { // SQL_errorCallback
console.log('Lookup SQL error ' err.code ' - ' err.message '.');
return true;
}
);
… но это не работает. Эта транзакция запускает все выборки, а затем выполняет вставки. Как я могу заставить второй метод работать?
Ответ №1:
Я предполагаю, что транзакция ставит запрос в очередь. Таким образом, ваша очередь будет выглядеть следующим образом
Выберите 1
Выберите 2
Выберите 3
Затем, когда вы фиксируете, ваша транзакция выглядит так после первого вызова.
Выберите 2
Выберите 3
Вставка 1
Вставьте 2
Вставьте 3
Это происходит потому, что функции для вызова вставок выполняются после запуска select, и этого не происходит до тех пор, пока транзакция не будет зафиксирована, но выбранные элементы уже зарегистрированы.
Для того, чтобы заставить его быть
выберите 1
insert1
выберите 2
insert2
Я бы создал отдельную транзакцию для каждого оператора select.
Комментарии:
1. НЕ ВЫПОЛНЯЙТЕ МЕТОД 2! Метод 1 занимает 22 секунды с 28 439 записями. Метод 2 с оболочкой транзакции, предложенный Майклом, занимает 34 секунды для того же количества записей!
2. Как вы можете сразу вставлять записи и как вы получаете данные для ввода. Я предполагал, что пользователи просто вводят пару записей за раз, так ли это, или вы вставляете 28 439 записей одновременно?
3. Данные поступают из файлов JSON. Вместо того, чтобы искать, а затем вставлять, я создаю массивы в памяти для хранения уникальных значений для таблиц, а затем использую этот меньший массив для выполнения вставок.