SQLStatement.execute() - multiple queries in one statement

Apache FlexActionscript 3Air

Apache Flex Problem Overview


I've written a database generation script in SQL and want to execute it in my Adobe AIR application:

Create Table tRole (
    roleID integer Primary Key
    ,roleName varchar(40)
);
Create Table tFile (
    fileID integer Primary Key
    ,fileName varchar(50)
    ,fileDescription varchar(500)
    ,thumbnailID integer
    ,fileFormatID integer
    ,categoryID integer
    ,isFavorite boolean
    ,dateAdded date
    ,globalAccessCount integer
    ,lastAccessTime date
    ,downloadComplete boolean
    ,isNew boolean
    ,isSpotlight boolean
    ,duration varchar(30)
);
Create Table tCategory (
    categoryID integer Primary Key
    ,categoryName varchar(50)
    ,parent_categoryID integer
);
...

I execute this in Adobe AIR using the following methods:

public static function RunSqlFromFile(fileName:String):void {
    var file:File = File.applicationDirectory.resolvePath(fileName);
    var stream:FileStream = new FileStream();
    stream.open(file, FileMode.READ)
    var strSql:String = stream.readUTFBytes(stream.bytesAvailable);
    NonQuery(strSql);
}

public static function NonQuery(strSQL:String):void {
    var sqlConnection:SQLConnection = new SQLConnection();
    sqlConnection.open(File.applicationStorageDirectory.resolvePath(DBPATH));
    var sqlStatement:SQLStatement = new SQLStatement();
    sqlStatement.text = strSQL;
    sqlStatement.sqlConnection = sqlConnection;
    try {
        sqlStatement.execute();
    } catch (error:SQLError) {
        Alert.show(error.toString());
    }
}

No errors are generated, however only tRole exists. It seems that it only looks at the first query (up to the semicolon- if I remove it, the query fails). Is there a way to call multiple queries in one statement?

Apache Flex Solutions


Solution 1 - Apache Flex

I wound up using this. It is a kind of a hack, but it actually works pretty well.

The only thing is you have to be very careful with your semicolons. : D

var strSql:String = stream.readUTFBytes(stream.bytesAvailable);		 
var i:Number = 0;
var strSqlSplit:Array = strSql.split(";");
for (i = 0; i < strSqlSplit.length; i++){
    NonQuery(strSqlSplit[i].toString());
}

Solution 2 - Apache Flex

The SQLite API has a function called something like sqlite_prepare which takes one statement and prepares it for execution, essentially parsing the SQL and storing it in memory. This means that the SQL only has to be sent once to the database engine even though the statement is executed many times.

Anyway, a statement is a single SQL query, that's just the rule. The AIR SQL API doesn't allow sending raw SQL to SQLite, only single statements, and the reason is, likely, that AIR uses the sqlite_prepare function when it talks to SQLite.

Solution 3 - Apache Flex

What about making your delimiter something a little more complex like ";\n" which would not show up all that often. You just have to ensure when creating the file you have a line return or two in there. I end up putting two "\n\n" into the creation of my files which works well.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShawnView Question on Stackoverflow
Solution 1 - Apache FlexShawnView Answer on Stackoverflow
Solution 2 - Apache FlexTheoView Answer on Stackoverflow
Solution 3 - Apache FlexstatsView Answer on Stackoverflow