Actionscript SQLite Insert Statements in a transaction
I'm trying to get my head around how to do a SQLite bulk insert using transactions in Flex / Actionscript 3 (using Adobe Air 2). This works, but it doesn't make sense to re-create a new SQLStatement in the loop:
private function onAddBulkContacts():void {
_responder = new Responder(resultEventHandler, errorEventHandler);
contacts_db.connection.begin(null, _responder);
var statement:SQLStatement;
for (var i:uint=0; i<parseInt(bulkAdd.numberToAdd.text); i++) {
statement = new SQLStatement();
statement.sqlConnection = contacts_db.connection;
statement.text ="INSERT INTO contacts ('name', 'lastname') VALUES (@NAME, @LASTNAME)";
statement.addEventListener(SQLErrorEvent.ERROR, function(event:Event):void {
trace('statement error');});
statement.addEventListener(SQ开发者_JAVA百科LEvent.RESULT, function(event:Event):void { trace('result'); });
statement.parameters['@NAME'] = "Name " + i.toString();
statement.parameters['@LASTNAME'] = "LastName " + i.toString();
statement.execute();
}
contacts_db.connection.commit();
}
What I want to do is create the SQLStatement once, let it compile, then just pass in new arguments within the loop, the commit it at the end, e.g.
private function onAddBulkContacts():void {
_responder = new Responder(resultEventHandler, errorEventHandler);
contacts_db.connection.begin(null, _responder);
var statement:SQLStatement;
statement = new SQLStatement();
statement.sqlConnection = contacts_db.connection;
statement.text ="INSERT INTO contacts ('name', 'lastname') VALUES (@NAME, @LASTNAME)";
statement.addEventListener(SQLErrorEvent.ERROR, function(event:Event):void {
trace('statement error');});
statement.addEventListener(SQLEvent.RESULT, function(event:Event):void { trace('result'); });
for (var i:uint=0; i<parseInt(bulkAdd.numberToAdd.text); i++) {
statement.parameters['@NAME'] = "Name " + i.toString();
statement.parameters['@LASTNAME'] = "LastName " + i.toString();
statement.execute();
}
contacts_db.connection.commit();
}
But the latter code throw an error saying that it can't execute the second time through, since the statement itself is still executing (and I believe will be in that state until the commit). I guess I can understand that the statements get added to the execution queue, but it doesn't make sense that I have to add the SQL text within the loop, exactly the thing I'm trying to avoid. I'm sure there's a better way to do this, but I've spent way too long hacking and reading trying to figure out what the proper sequence is. Any ideas?
Haven't done bulk inserts in AIR, but typically one creates the statement outside the loop, initiates the transaction; then with each iteration of the loop binds new parameter values and executes the statement; then outside the loop, commit.
Is the database opened in synchronous or asynchronous mode?
In asynch mode:
... the simplest way to organize the application to ensure that the operations are executed properly is to create a method that’s registered as a listener for the begin event. The code to call the SQLStatement.execute() method is placed within that listener method.
http://help.adobe.com/en_US/AIR/1.5/devappshtml/WS5b3ccc516d4fbf351e63e3d118666ade46-7d2b.html
You could also try getting the next set of values to be bound to the statement parameters using the array.shift() method rather than in a loop; the array.shift() method would be invoked in the result handler; when the array is empty you'd commit; your error handler would issue a rollback.
精彩评论