无法在for循环中使用JavaScript创建SQLite表 [英] Unable to CREATE SQLite tables using JavaScript in for loop

查看:82
本文介绍了无法在for循环中使用JavaScript创建SQLite表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用AngularJS,JS,Phonegap/Cordova,Monaca和Onsen UI开发的跨平台应用程序.

I have a cross platform app developed using AngularJS, JS, Phonegap/Cordova, Monaca and Onsen UI.

我已经在应用程序中实现了一个SQLite数据库来存储各种数据,以确保可以离线使用该应用程序.我已经做了一些简单的测试,并且一切都按预期进行.

I have implemented a SQLite Database in the app to store various data to ensure that the app can be used offline. I have done a few simple tests and this is all working as intended.

我现在尝试在我的应用程序中首先查看 onDeviceReady()函数创建该应用程序中需要的所有表(总共28个).为此,我创建了一个对象数组,该对象数组将一一传递给SQLite CREATE语句,如下所示.

I now try to create all the tables I will need in the app (28 in total) in my apps first views onDeviceReady() function. For this I create an array of objects that I will pass one by one to the SQLite CREATE statement as below.

设置表格值

// Form values
var formValues = [{
    tablename: "table_1",
    id: "id_1",
    desc: "desc_1",
    dataType: "TEXT"
}, {
    tablename: "table_2",
    id: "id_2",
    desc: "desc_2",
    dataType: "TEXT"
}, {
    ...
    ...
    ...
    ...
}, {
    tablename: "table_28",
    id: "id_28",
    desc: "desc_28",
    dataType: "TEXT"
}];

创建表格

function onDeviceReady() {
    for (var i = 0; i < formValues.length; i++) {
        var createFormValues = 'CREATE TABLE IF NOT EXISTS ' + formValues[i].tablename + ' (' + formValues[i].id + ' INTEGER, ' + formValues[i].desc + ' ' + formValues[i].dataType + ')';
        alert("SQL: " + createFormValues +
            "\n\nForm: " + formValues +
            "\nName: " + formValues[i].tablename +
            "\nID: " + formValues[i].id +
            "\nDesc: " + formValues[i].desc +
            "\nType: " + formValues[i].dataType);

        db.transaction(function (tx) { tx.executeSql(createFormValues); });
    }
};

运行上面的代码时,警报显示包括SQL语句在内的所有信息均正常.但是,当我在for()循环之后查询每个表时,它说没有 EXCEPT 最后一个表被创建.

When I run the above code, the alert shows that all the information including the SQL statement is OK. However, when I query each table following the for() loop, it says no tables are created EXCEPT the last table.

然后我尝试以下操作,它们执行创建所有表,但是效率和可管理性显然较低.

I then try the following which DOES create all the tables but is obviously less efficient and manageable.

调用函数

createFormTables("table_1", "id_1", "desc_1", "TEXT");
createFormTables("table_2", "id_2", "desc_2", "TEXT");
createFormTables("...", "...", "...", "...");
createFormTables("table_28", "id_28", "desc_28", "TEXT");

执行功能

createFormTables: function (tableName, id, description, dataType) {
    var sql = 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + id + ' INTEGER, ' + description + ' ' + dataType + ')';
    alert("Create Form Field SQL: " + sql);
    db.transaction(function (tx) { tx.executeSql(sql); });
},

我知道SQLite语句是异步执行的,但是我不明白为什么要在第二个示例而不是第一个示例中创建表?如何使用第一个示例创建表?我可以设置一个 $ timeout 来执行每个 INSERT 语句,但这似乎不必要,并且会导致延迟.

I know that the SQLite statements are executed asynchronously but I dont understand why that would create the tables in the second example and not the first? How do I create the tables using the first example? I can set a $timeout to execute each INSERT statement but this seems unnecessary and will cause delays.

推荐答案

在调用函数"createFormTables"时,我将使用JavaScript对象"方法避免冲突:

I would use the JavaScript "Object" aproach to avoid conflict when calling function 'createFormTables' with something like:

var QuerySet = function(){
//OPTIONAL: I use JQuery Deferred to catch when an async event has finished
    this.defRes = new $.Deferred();
    this.defResProm = this.defRes.promise();
};

QuerySet.prototype.createFormTables= function(inputData){
      //do your stuff and manage when this.defRes is resolved and results it sends back (if a result is needed)
     this.sqlToExecute = "// YOUR SQL QUERY"; 
     var self=this;
    $.when(
        (new SqlResult(this.sqlToExecute)).execSqlCustomDeferred(), //read below for SqlResult() explanations
        self
    ).done(function(sqlRes,self){
        self.defRes.resolve();
    });

      return this.defResProm;
};

然后输入代码:

creatFromTables[i] = (new QuerySet()).createFormTables(inputData);
createFromTables[i].defRes.done(function(res){//do stuff with the result});

不需要使用$ .Deferred(),但我想如果您想知道何时创建了所有表,这可能会很有用.

Don't need to use $.Deferred() but I think it could be useful if you want to know when all the tables have been created.

这是sqlResult,用于在数据库本身上调用事务:

And here is sqlResult that is used to call the transaction on the DB itself:

var SqlResult = function(sqlToExecute,bracketValues){
            //console.log("SqlResult("+sqlToExecute+','+bracketValues+') starts');

    this.sqlToExecute = sqlToExecute;
    this.bracketValues =bracketValues;
};

SqlResult.prototype.execSqlCustomDeferred = function(){
        var execSqlCustomDeferredRes = $.Deferred();
        var execSqlCustomDeferredResProm = execSqlCustomDeferredRes.promise();  

        //console.log("SqlResult.execSqlCustomDeferred sqlToExecute is: "+this.sqlToExecute);
        var sqlToExecuteForTx = this.sqlToExecute;
        var bracketValuesForTx = this.bracketValues;

        DbManagement.db.transaction(function(tx){

            console.log("SqlResult.execSqlCustomDeferred in TX sqlToExecute is: "+sqlToExecuteForTx);

            if(bracketValuesForTx!=null){
                console.log("SqlResult.execSqlCustomDeferred bracket value is: "+ArrayManagement.arrayToString(bracketValuesForTx));
            }
            tx.executeSql(sqlToExecuteForTx,bracketValuesForTx,success,error);
            function success(tx,rs){
                //console.log('before execSqlCustomDeferredRes resolve ' + execSqlCustomDeferredRes.state());
                execSqlCustomDeferredRes.resolve(rs);
                //console.log('before execSqlCustomDeferredRes resolve  after ' + execSqlCustomDeferredRes.state());

            }
            function error(tx,error){
                console.log('execSqlCustomDeferred error ' + error.message);
                execSqlCustomDeferredRes.reject(error);
            }

            });

        return execSqlCustomDeferredResProm;
};

这篇关于无法在for循环中使用JavaScript创建SQLite表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆