Reputation: 255
First of all, I am new to SQLite.
I try to make an AIR application that can import value from excel file into SQLite database. What I try do to is to make a loop that allow me to insert data from excel into SQLite database. Below is my code;
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.SQLEvent;
import flash.events.TimerEvent;
import flash.data.SQLStatement;
import flash.data.SQLConnection;
import flash.utils.Timer;
import flash.filesystem.File;
import flash.net.FileFilter;
import fl.controls.Button;
import fl.controls.DataGrid;
import fl.controls.ScrollPolicy;
import lib.xlsxreader.Worksheet;
import lib.xlsxreader.XLSXLoader;
public class DataTransfer extends MovieClip
{
private var i;
private var fileGet: File = new File();
private var dbFile: File = new File();
private var excel_loader: XLSXLoader = new XLSXLoader();
private var sqlc: SQLConnection = new SQLConnection();
private var sqls: SQLStatement = new SQLStatement();
public function DataTransfer()
{
var btnImport: Button = new Button();
btnImport.x = btnImport.y = 10;
btnImport.label = "Select Excel File";
btnImport.addEventListener(MouseEvent.CLICK, selectExcelFile);
addChild(btnImport);
fileGet = File.applicationDirectory;
fileGet.addEventListener(Event.CANCEL, fileCancel);
fileGet.addEventListener(Event.SELECT, fileSelect);
dbFile = fileGet.resolvePath("test.sqlite");
excel_loader.addEventListener(Event.COMPLETE, loadingComplete);
sqlc.addEventListener(SQLEvent.OPEN, db_opened);
sqlc.openAsync(dbFile);
}
private function selectExcelFile(e: MouseEvent): void
{
var fileFilter = new FileFilter("Select Excel File", "*.xls;*.xlsx;*.xlsm");
fileGet.browseForOpen("Select Excel File", [fileFilter]);
}
private function fileCancel(e: Event): void
{
trace("Cancel");
}
private function fileSelect(e: Event): void
{
trace("File Path is : " + fileGet.nativePath);
excel_loader.load(fileGet.nativePath);
}
private function loadingComplete(e: Event): void
{
var row: int = new int();
var sheet_2: Worksheet = excel_loader.worksheet("Sheet2");
var arColumn1: Array = new Array();
var arColumn2: Array = new Array();
var arColumn3: Array = new Array();
row = sheet_2.rows;
sqls.text = ""
for (i = 1; i <= row; i++)
{
arColumn1[i - 1] = sheet_2.getCellValue("A" + i);
arColumn2[i - 1] = sheet_2.getCellValue("B" + i);
arColumn3[i - 1] = sheet_2.getCellValue("C" + i);
sqls.text = sqls.text + "INSERT INTO test_table (col1) VALUES('" + arColumn1[i - 1] + "');";
}
trace(sqls.text);
sqls.execute();
refresh();
var dtExcel: DataGrid = new DataGrid();
dtExcel.x = 10;
dtExcel.y = 40;
dtExcel.width = 300;
dtExcel.height = 100;
dtExcel.horizontalScrollPolicy = ScrollPolicy.ON;
dtExcel.verticalScrollPolicy = ScrollPolicy.ON;
var col1 = dtExcel.addColumn("Column1");
var col2 = dtExcel.addColumn("Column2");
var col3 = dtExcel.addColumn("Column3");
col1.minWidth = 100;
col2.minWidth = 200;
col3.minWidth = 300;
for (i = 0; i <= row - 1; i++)
{
dtExcel.addItem(
{
Column1: arColumn1[i],
Column2: arColumn2[i],
Column3: arColumn3[i]
});
}
addChild(dtExcel);
}
private function db_opened(e: SQLEvent): void
{
sqls.sqlConnection = sqlc;
sqls.text = "CREATE TABLE IF NOT EXISTS test_table (id INTEGER PRIMARY KEY AUTOINCREMENT, col1 TEXT, col2 TEXT, col3 TEXT)";
sqls.execute();
refresh();
}
private function refresh(e: TimerEvent = null): void
{
var timer: Timer = new Timer(10, 1);
timer.addEventListener(TimerEvent.TIMER, refresh);
if (!sqls.executing)
{
sqls.text = "SELECT * FROM test_table";
sqls.execute();
}
else
{
timer.start();
}
}
}
}
I have problem at this line;
for (i = 1; i <= row; i++)
{
arColumn1[i - 1] = sheet_2.getCellValue("A" + i);
arColumn2[i - 1] = sheet_2.getCellValue("B" + i);
arColumn3[i - 1] = sheet_2.getCellValue("C" + i);
sqls.text = sqls.text + "INSERT INTO test_table (col1) VALUES('" + arColumn1[i - 1] + "');";
}
I try to loop the sqls.text
so that the excel value can be pass into the SQLite database. However sqls.execute()
only execute the first INSERT
.
I try to see the value of sqls.text
using trace(sqls.text)
and I think my SQL statement is correct (assuming that SQLite do use PostgreSQL syntax) as shown below;
INSERT INTO test_table (col1) VALUES('saya');INSERT INTO test_table (col1) VALUES('makan');INSERT INTO test_table (col1) VALUES('minum');INSERT INTO test_table (col1) VALUES('');INSERT INTO test_table (col1) VALUES('');INSERT INTO test_table (col1) VALUES('main');
I assume my syntax is correct as I use the above syntax in https://rextester.com/l/postgresql_online_compiler and it work just fine.
I assume my looping implementation is correct because my datagrid dtExcel
show the exact correct value in correct column and row.
I also try to use sqls.execute()
in the loop but I get the following error:
Error: Error #3106: Property cannot be changed while SQLStatement.executing is true.
Is there are way to do this loop? Or I need to use open source AS3 SQLite library to do this?
Edit:
According to here, I can change the above SQLite syntax into;
INSERT INTO test_table (col1) VALUES('saya'),('makan'),('minum'),(''),(''),('main');
However, this still give following error;
Error #2044: Unhandled SQLErrorEvent:. errorID=3115, operation=execute , message=Error #3115: SQL Error. , details=near ',': syntax error
Upvotes: 0
Views: 229
Reputation: 132
Try to make one command per each loop together with execute and parameters in the prepared statement:
for (i = 1; i <= row; i++)
{
arColumn1[i - 1] = sheet_2.getCellValue("A" + i);
arColumn2[i - 1] = sheet_2.getCellValue("B" + i);
arColumn3[i - 1] = sheet_2.getCellValue("C" + i);
sqls.clearParameters();
sqls.text = "INSERT INTO test_table (col1, col2, col3) VALUES(:param1, :param2, :param3)";
sqls.parameters[":param1"] = arColumn1[i - 1];
sqls.parameters[":param2"] = arColumn2[i - 1];
sqls.parameters[":param3"] = arColumn3[i - 1];
sqls.execute();
}
Also, you could use transaction:
sqls.begin();
- for loop here
sqls.commit();
Upvotes: 2