向sql lite添加记录时滞后

时间:2016-09-02 09:38:55

标签: sqlite actionscript-3 flash air

我做了一个应用程序(Adobe Air)。在大多数情况下,该应用程序按预期工作。我遇到的一个问题是在向sql lite添加新记录时。添加新记录(100+)时,应用程序似乎挂起10-20秒,同时将记录添加到sql lite。我知道这是因为动画停止了,没有其他代码触发。 添加记录后,应用程序正常运行。

以下是问题发生的代码。

    var k:Number = 0
    var arrCount:Number = cleanedArray.length
    while(k<arrCount){
        if(executeStatement("INSERT INTO wcs_tasks (taskID, stockID, rackID, pickID, countID)values('"+taskNumber+"', '"+cleanedArray[k][0]+"', '"+cleanedArray[k][1]+"', '"+cleanedArray[k][2]+"', '"+cleanedArray[k][3]+"')","0","0")[0].id == "-1"){
            k++
        }
    }

我最初尝试使用for(),但也显示了同样的问题。添加记录后运行任何其他查询都可以正常运行,并且查询响应时间很短。

下面是处理所有sql lite查询的函数。

    function executeStatement(stmtText:String, param1:String, param2:String):Array {
if (conn.connected) {
    var arr:Array = new Array();
    stmt = new SQLStatement();
    stmt.sqlConnection = conn;

    stmt.text = stmtText;
    //stmt.parameters[0] = param1;
    //stmt.parameters[1] = param2;
    var row;
    try {
        stmt.execute();
        var result:SQLResult = stmt.getResult();

        if (result.data != null) {
            var total:int = result.data.length;
            for (var i:int = 0; i < total; i++) {
                row = result.data[i];
                arr.push( { id:row } );
            }
        } else {
            arr.push({id: -1});//no result/s
        }
    } catch (error:SQLError) {
        trace(error);
        arr.push({id: -2});//sqlite error
    }
} else {
    arr.push({id: -3});//no connection
}
return arr;

}

1 个答案:

答案 0 :(得分:1)

是的,在循环中将大量条目插入数据库可能在移动设备上很慢。有两种解决方案:

  1. 使用异步数据库连接。你有一个同步的,这意味着应用程序将等待一个语句执行,然后执行下一个语句。在异步连接中,您只需发送一堆语句,它们将在后台执行。在某些时候,您将从DB获得响应(结果或失败)。缺点是你需要一个更复杂的错误处理(如果你依赖项目成功添加到你的数据库但是它没有。或者它还没有被添加。你怎么办。
  2. 这就是这样的:

    conn = new SQLConnection();
    conn.addEventListener(SQLEvent.OPEN, openSuccess);
    conn.addEventListener(SQLErrorEvent.ERROR, openFailure);
    
    var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
    conn.openAsync(dbFile);
    

    然后你做你的陈述:

    stmt = new SQLStatement();
    stmt.sqlConnection = conn;
    stmt.text = stmtText;
    stmt.addEventListener(SQLEvent.RESULT, dbResult);
    stmt.addEventListener(SQLErrorEvent.ERROR, dbError);
    stmt.execute();
    
    private function dbResult(event:SQLEvent):void
    {
        var stmt:SQLStatement = event.target as SQLStatement;
        stmt.removeEventListener(SQLEvent.RESULT, dbResult);
        stmt.removeEventListener(SQLErrorEvent.ERROR, dbError);
    }
    
    private function dbError(event:SQLEvent):void
    {
        stmt.removeEventListener(SQLEvent.RESULT, dbResult);
        stmt.removeEventListener(SQLErrorEvent.ERROR, dbError);
    }
    
    1. 另一种解决方案是将数据库作业分配到多个帧。将语句放入数组中,添加一个enterframe事件侦听器,并在每个帧上只执行数组中的一些语句。完成后,将其从阵列中删除。继续这样做,直到你的数组为空:)