(SQLite + Javascript) проблема с INSERT с последующим SELECT в цикле for - PullRequest
2 голосов
/ 18 февраля 2012

У меня проблема со следующим, и я думаю, это связано с асинхронным режимом SQLite. Код довольно длинный, поэтому я попытаюсь объяснить вкратце. У меня 4 входа

<input id="input0" name="tbleName3">
<input id="input1" name="tbleName4">
<input id="input2" name="tbleName1">
<input id="input3" name="tbleName1">

На самом деле, в моем приложении количество входов не фиксировано и динамически изменяется пользователем. Порядок ввода идентификатора является фиксированным, то есть индекс является инкрементным индексом ++ ... Однако имя может быть изменено динамически. Имя ввода - это имя таблицы в БД. Вот что я пытаюсь сделать: я помещаю все имена в массив. arrInput = массив (tbleName3, tbleName4, tbleName1, tbleName1). Теперь я хочу частично заполнить каждую таблицу БД, имя которой находится в массиве, и получить вновь созданные значения идентификатора в каждой из таблиц. Обратите внимание, что все таблицы имеют одинаковые два первых столбца: tablePattern [id INT, немного TXT, ......]

db.transaction(function(tx) {
   for(var i=0; i < arrInput.length; i++){
      var thisTble = arrInput[i];
      var insertSqlArg = "INSERT INTO "+thisTble+" (some) VALUES (?)";
      tx.executeSql(insertSqlArg, ["thing"], (function(i, thisTble){return     function(tx,resultIdNew){
         var selectSqlArg = "SELECT id from "+thisTble+" order by id DESC limit 1";
         tx.executeSql(selectSqlArg, [], function(tx,resultId){
        var datasetId = resultId.rows;
            var itemId = datasetId.item(0);
        var idValue = itemId['id'];
        alert("i="+i+", tbleName="+thisTble+", New id="+idValue);
         }), fnError);
      };})(i, thisTble), fnError);
   }
}

Если имена четырех входов различаются (например, {tbleName1, tbleName2, tbleName3, tbleName4}), код работает отлично. Ошибка возникает, когда 2 или более входов используют одно и то же имя (например, {tbleName1, tbleName2, tbleName3, tbleName3}), т.е. 1 строка добавляется в tbleName1 и tbleName2, а 2 строки в tbleName3. В этом случае вместо того, чтобы сообщать идентификатор первой созданной строки (для момента 14), а затем второй созданной строки (15) в tbleName3, в окне предупреждения будет показан дважды идентификатор самой последней добавленной строки (15). Я не знаю, как это исправить. Похоже, что команда для создания 2-й строки запускается до того, как будет прочитан идентификатор строки, созданной первой.

// Конечная цель кода - вставить idValue и thisTble в другую таблицу «flowTble». Линия:

alert("i="+i+", tbleName="+thisTble+", New id="+idValue);

фактически заменен на:

var insertFlow = "INSERT INTO flowTble (some, tbleName, idTbleName, index) VALUES (thing, ?, ?, ?)";
tx.executeSql(insertFlow , [tbleName, idValue, i], null, onError);

Проблема остается той же, хотя (выбор дает только самый последний созданный идентификатор). Тем не менее, я мог бы иметь больше шансов, используя «Триггер», который запускался сразу после "INSERT INTO "+thisTble+" (some) VALUES (?)", и вставлял набор значений в flowTble. НО, я не знаю, как создать такой триггер с помощью JS-оболочки. Вот попытка:

var createTrigger = "CREATE TRIGGER fillFlowTble AFTER INSERT ON "+TbleName+" FOR EACH ROW INSERT INTO flowTble (some, tbleName, idTbleName, index) VALUES (thing, tbleName, idValue, i)";
db.transaction(function(tx) {
    tx.executeSql(createTrigger, [], null, onError);
});
...