本章主要總結(jié)關(guān)系數(shù)據(jù)庫(kù)引擎
(sqlite),
同步和異步執(zhí)行模式
,
創(chuàng)建數(shù)據(jù)庫(kù)和表
?
Adobe AIR
包括一個(gè)基于
SQL
的關(guān)系數(shù)據(jù)庫(kù)引擎
(sqlite)
,該引擎在運(yùn)行時(shí)中運(yùn)行,數(shù)據(jù)以本地方式存儲(chǔ)在運(yùn)行
AIR
應(yīng)用程序的計(jì)算機(jī)上的數(shù)據(jù)庫(kù)文件中(例如,在計(jì)算機(jī)的硬盤(pán)驅(qū)動(dòng)器上)。由于數(shù)據(jù)庫(kù)的運(yùn)行和數(shù)據(jù)文件的存儲(chǔ)都在本地進(jìn)行,因此,不管網(wǎng)絡(luò)連接是否可用,
AIR
應(yīng)用程序都可以使用數(shù)據(jù)庫(kù)。
單個(gè)
Adobe AIR
本地
SQL
數(shù)據(jù)庫(kù)作為單個(gè)文件存儲(chǔ)在計(jì)算機(jī)的文件系統(tǒng)中。運(yùn)行時(shí)包括
SQL
數(shù)據(jù)庫(kù)引擎,該引擎管理數(shù)據(jù)庫(kù)文件的創(chuàng)建和結(jié)構(gòu)化以及操作和檢索數(shù)據(jù)庫(kù)文件中的數(shù)據(jù)。運(yùn)行時(shí)不指定在文件系統(tǒng)上存儲(chǔ)數(shù)據(jù)庫(kù)數(shù)據(jù)的方式或位置;相反,每個(gè)數(shù)據(jù)庫(kù)完全存儲(chǔ)在單個(gè)文件中。您指定在文件系統(tǒng)中存儲(chǔ)數(shù)據(jù)庫(kù)文件的位置。單個(gè)
AIR
應(yīng)用程序可以訪(fǎng)問(wèn)一個(gè)或多個(gè)單獨(dú)的數(shù)據(jù)庫(kù)(即單獨(dú)的數(shù)據(jù)庫(kù)文件)。由于運(yùn)行時(shí)將每個(gè)數(shù)據(jù)庫(kù)作為單個(gè)文件存儲(chǔ)在文件系統(tǒng)上,因此可以在需要時(shí)按照應(yīng)用程序的設(shè)計(jì)和操作系統(tǒng)的文件訪(fǎng)問(wèn)約束查找您的數(shù)據(jù)庫(kù)。每個(gè)用戶(hù)都可以具有其特定數(shù)據(jù)的單獨(dú)數(shù)據(jù)庫(kù)文件,或者數(shù)據(jù)庫(kù)文件可以由在單個(gè)計(jì)算機(jī)上共享數(shù)據(jù)的所有應(yīng)用程序用戶(hù)訪(fǎng)問(wèn)。由于數(shù)據(jù)對(duì)單個(gè)計(jì)算機(jī)是本地的,因此在不同計(jì)算機(jī)上的用戶(hù)之間并不自動(dòng)共享數(shù)據(jù)。本地
SQL
數(shù)據(jù)庫(kù)引擎未提供對(duì)遠(yuǎn)程數(shù)據(jù)庫(kù)或基于服務(wù)器的數(shù)據(jù)庫(kù)執(zhí)行
SQL
語(yǔ)句的任何功能。
?
關(guān)于
sqlite
關(guān)于
SQLite
的特性
:
1. ACID
事務(wù)
2.
零配置
–
無(wú)需安裝和管理配置
3.
儲(chǔ)存在單一磁盤(pán)文件中的一個(gè)完整的數(shù)據(jù)庫(kù)
4.
數(shù)據(jù)庫(kù)文件可以在不同字節(jié)順序的機(jī)器間自由的共享
5.
支持?jǐn)?shù)據(jù)庫(kù)大小至
2TB
6.
足夠小
,
大致
3
萬(wàn)行
C
代碼
, 250K
7.
比一些流行的數(shù)據(jù)庫(kù)在大部分普通數(shù)據(jù)庫(kù)操作要快
8.
簡(jiǎn)單
,
輕松的
API
9.
包含
TCL
綁定
,
同時(shí)通過(guò)
Wrapper
支持其他語(yǔ)言的綁定
10.
良好注釋的源代碼
,
并且有著
90%
以上的測(cè)試覆蓋率
11.
獨(dú)立
:
沒(méi)有額外依賴(lài)
12.
Source完全的Open, 你可以用于任何用途, 包括出售它
13. 支持多種開(kāi)發(fā)語(yǔ)言,C, PHP, Perl, Java, ASP.NET,Python
更詳細(xì)情況可以參考以下站點(diǎn):
http://www.sqlite.org/
http://www.sqlite.com.cn/
?
本地
SQL
數(shù)據(jù)庫(kù)的用途
AIR
本地
SQL
數(shù)據(jù)庫(kù)功能可以用于將應(yīng)用程序數(shù)據(jù)存儲(chǔ)在用戶(hù)的本地計(jì)算機(jī)上的任何目的。
Adobe AIR
包括在本地存儲(chǔ)數(shù)據(jù)的幾種機(jī)制,各機(jī)制具有不同的優(yōu)點(diǎn)。以下是本地
SQL
數(shù)據(jù)庫(kù)在
AIR
應(yīng)用程序中的一些可能用途:
1.
對(duì)于面向數(shù)據(jù)的應(yīng)用程序(例如通訊簿),數(shù)據(jù)庫(kù)可以用于存儲(chǔ)主應(yīng)用程序數(shù)據(jù)。
2.
對(duì)于面向文檔的應(yīng)用程序(用戶(hù)創(chuàng)建要保存并可能共享的文檔),可以在用戶(hù)指定的位置將每個(gè)文檔另存為數(shù)據(jù)庫(kù)文件。(但是,請(qǐng)注意,任何
AIR
應(yīng)用程序都能夠打開(kāi)數(shù)據(jù)庫(kù)文件,因此對(duì)于潛在敏感的文檔,建議使用單獨(dú)的加密機(jī)制。)
3.
對(duì)于支持網(wǎng)絡(luò)的應(yīng)用程序,數(shù)據(jù)庫(kù)可以用于存儲(chǔ)應(yīng)用程序數(shù)據(jù)的本地緩存,或者在網(wǎng)絡(luò)連接不可用時(shí)暫時(shí)存儲(chǔ)數(shù)據(jù)。可以創(chuàng)建一種將本地?cái)?shù)據(jù)庫(kù)與網(wǎng)絡(luò)數(shù)據(jù)存儲(chǔ)同步的機(jī)制。
4.
對(duì)于任何應(yīng)用程序,數(shù)據(jù)庫(kù)都可以用于存儲(chǔ)單個(gè)用戶(hù)的應(yīng)用程序設(shè)置,例如用戶(hù)選項(xiàng)或應(yīng)用程序信息(如窗口大小和位置)。
?
關(guān)于同步和異步執(zhí)行模式
1.
編寫(xiě)代碼以處理本地
SQL
數(shù)據(jù)庫(kù)時(shí),會(huì)指定以?xún)煞N執(zhí)行模式之一執(zhí)行數(shù)據(jù)庫(kù)操作:異步或同步執(zhí)行模式。通常,代碼示例說(shuō)明如何以這兩種方式執(zhí)行每個(gè)操作,以便您可以使用最適合您需求的示例。
2.
在異步執(zhí)行模式中,為運(yùn)行時(shí)提供一個(gè)指令,運(yùn)行時(shí)將在請(qǐng)求的操作完成或失敗時(shí)調(diào)度事件。首先,通知數(shù)據(jù)庫(kù)引擎執(zhí)行操作。在應(yīng)用程序繼續(xù)運(yùn)行的同時(shí),數(shù)據(jù)庫(kù)引擎在后臺(tái)工作。最后,完成操作時(shí)(或者它失敗時(shí)),數(shù)據(jù)庫(kù)引擎調(diào)度事件。由事件觸發(fā)的代碼執(zhí)行后續(xù)操作。此方法具有一個(gè)重要的優(yōu)點(diǎn):運(yùn)行時(shí)在后臺(tái)執(zhí)行數(shù)據(jù)庫(kù)操作,同時(shí)主應(yīng)用程序代碼繼續(xù)執(zhí)行。如果數(shù)據(jù)庫(kù)操作花費(fèi)大量的時(shí)間,則應(yīng)用程序繼續(xù)運(yùn)行。最重要的是,用戶(hù)可以繼續(xù)與其交互,而屏幕不會(huì)凍結(jié)。但是,與其它代碼相比,編寫(xiě)異步操作代碼可能更加復(fù)雜。在必須將多個(gè)相關(guān)的操作分配給各個(gè)事件偵聽(tīng)器方法的情況下,通常會(huì)出現(xiàn)此復(fù)雜性。
3.
從概念上說(shuō),將操作作為單個(gè)步驟序列(一組同步操作,而不是分到幾個(gè)事件偵聽(tīng)器方法中的一組操作)進(jìn)行編碼更為簡(jiǎn)單。除了異步數(shù)據(jù)庫(kù)操作外,
Adobe AIR
還允許您同步執(zhí)行數(shù)據(jù)庫(kù)操作。在同步執(zhí)行模式中,操作不在后臺(tái)運(yùn)行。相反,它們以與所有其它應(yīng)用程序代碼相同的執(zhí)行序列運(yùn)行。通知數(shù)據(jù)庫(kù)引擎執(zhí)行操作。然后,代碼在數(shù)據(jù)庫(kù)引擎工作時(shí)暫停。完成操作后,繼續(xù)執(zhí)行下一行代碼。
4.
異步還是同步執(zhí)行操作是在
SQLConnection
級(jí)別上設(shè)置的。使用單個(gè)數(shù)據(jù)庫(kù)連接,無(wú)法同步執(zhí)行某些操作或語(yǔ)句,同時(shí)異步執(zhí)行其它操作或語(yǔ)句。通過(guò)調(diào)用
SQLConnection
方法打開(kāi)數(shù)據(jù)庫(kù),可以指定
SQLConnection
是在同步還是異步執(zhí)行模式下操作。如果調(diào)用
SQLConnection.open()
,則連接在同步執(zhí)行模式下操作;如果調(diào)用
SQLConnection.openAsync()
,則連接在異步執(zhí)行模式下操作。使用
open()
或
openAsync()
將
SQLConnection
實(shí)例連接到數(shù)據(jù)庫(kù)后,除非先關(guān)閉再重新打開(kāi)到數(shù)據(jù)庫(kù)的連接,否則該實(shí)例將固定為同步或異步執(zhí)行模式。
?
創(chuàng)建數(shù)據(jù)庫(kù)
若要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù)文件,請(qǐng)首先創(chuàng)建 SQLConnection 實(shí)例。調(diào)用其 open() 方法在同步執(zhí)行模式下打開(kāi)它,或者調(diào)用其 openAsync() 方法在異步執(zhí)行模式下打開(kāi)它。open() 和 openAsync() 方法用于打開(kāi)到數(shù)據(jù)庫(kù)的連接。如果傳遞的 File 實(shí)例引用 reference 參數(shù)(第一個(gè)參數(shù))的不存在的文件位置,則 open() 或 openAsync() 方法將在該文件位置創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)文件,并打開(kāi)到新創(chuàng)建的數(shù)據(jù)庫(kù)的連接。
不管是調(diào)用
open()
方法還是
openAsync()
方法創(chuàng)建數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)文件的名稱(chēng)都可以是具有任何文件擴(kuò)展名的任何有效文件名。如果調(diào)用
reference
參數(shù)為
null
的
open()
或
openAsync()
方法,
則將創(chuàng)建新的內(nèi)存中數(shù)據(jù)庫(kù),而不是在磁盤(pán)上創(chuàng)建數(shù)據(jù)庫(kù)文件
。
以下代碼清單說(shuō)明使用
異步執(zhí)行
模式創(chuàng)建數(shù)據(jù)庫(kù)文件(新數(shù)據(jù)庫(kù))的過(guò)程
,
數(shù)據(jù)庫(kù)文件保存在應(yīng)用程序的存儲(chǔ)目錄中,其文件名為
“myTestdb.db”
:
import mx.controls.Alert;
private var con:SQLConnection;
private function initApp():void
{
?var file:File = File.applicationStorageDirectory.resolvePath("myTestdb.db")
?
?con = new SQLConnection();
?//在 openAsync() 方法調(diào)用操作成功完成時(shí)調(diào)度
?con.addEventListener(SQLEvent.OPEN,openHandler);
?//SQLConnection 對(duì)象的異步操作導(dǎo)致錯(cuò)誤時(shí)調(diào)度
?con.addEventListener(SQLErrorEvent.ERROR,errorHandler);
?
?con.openAsync(file);
}
private function openHandler(evt:SQLEvent):void
{
?Alert.show("成功完成");
}
private function errorHandler(evt:SQLErrorEvent):void
{
?Alert.show("失敗");
?Alert.show(evt.error.message);
?Alert.show(evt.error.details);
}
要
同步執(zhí)行
操作,請(qǐng)?jiān)谑褂?SQLConnection 實(shí)例打開(kāi)數(shù)據(jù)庫(kù)連接時(shí),調(diào)用 open() 方法。以下代碼說(shuō)明如何創(chuàng)建和打開(kāi)同步執(zhí)行其操作的 SQLConnection 實(shí)例:
import mx.controls.Alert;
private var con:SQLConnection;
private function initApp():void
{
?var file:File = File.applicationStorageDirectory.resolvePath("myTestdb.db")
?
?con = new SQLConnection();
?
?try
?{
??con.open(file);
??Alert.show("成功完成");
?}
?catch(error:SQLError)
?{
??Alert.show(error.message);
??Alert.show(error.details);
?}
}
?
創(chuàng)建數(shù)據(jù)庫(kù)表
以下使用
異步執(zhí)行
模式在現(xiàn)有數(shù)據(jù)庫(kù)文件中創(chuàng)建一個(gè)名為
“emp”
的表。
import mx.controls.Alert;
private var con:SQLConnection;
private var createStmt:SQLStatement;
private function initApp():void
{
?var file:File = File.applicationStorageDirectory.resolvePath("myTestdb.db")
?
?con = new SQLConnection();
?//在 openAsync() 方法調(diào)用操作成功完成時(shí)調(diào)度
?con.addEventListener(SQLEvent.OPEN,openHandler);
?//SQLConnection 對(duì)象的異步操作導(dǎo)致錯(cuò)誤時(shí)調(diào)度
?con.addEventListener(SQLErrorEvent.ERROR,errorHandler);
?
?con.openAsync(file);
}
private function createResult(event:SQLEvent):void
{
??? Alert.show("表創(chuàng)建");
}
private function createError(event:SQLErrorEvent):void
{
??? Alert.show("Error message:", event.error.message);
??? Alert.show("Details:", event.error.details);
}
private function openHandler(evt:SQLEvent):void
{
?Alert.show("成功完成");
?
?createStmt = new SQLStatement();
?createStmt.sqlConnection = con;
?var sql:String =?
??? "CREATE TABLE IF NOT EXISTS emp (" +?
??? "??? empId INTEGER PRIMARY KEY AUTOINCREMENT, " +?
??? "??? firstName TEXT, " +?
??? "??? lastName TEXT, " +?
??? "??? salary NUMERIC CHECK (salary > 0)" +?
??? ")";
???
?createStmt.text = sql;
?createStmt.addEventListener(SQLEvent.RESULT, createResult);
?createStmt.addEventListener(SQLErrorEvent.ERROR, createError);
?createStmt.execute();?
}
private function errorHandler(evt:SQLErrorEvent):void
{
?Alert.show("失敗");
?Alert.show(evt.error.message);
?Alert.show(evt.error.details);
}
以下代碼使用
同步執(zhí)行
模式在現(xiàn)有數(shù)據(jù)庫(kù)文件中創(chuàng)建一個(gè)名為“emp”的表
import mx.controls.Alert;
private var con:SQLConnection;
private var createStmt:SQLStatement;
private function initApp():void
{
?var file:File = File.applicationStorageDirectory.resolvePath("myTestdb.db")
?
?con = new SQLConnection();
?createStmt = new SQLStatement();
?
?try
?{
??con.open(file);
??
??
??createStmt.sqlConnection = con;
??var sql:String =?
??? ?"CREATE TABLE IF NOT EXISTS emp (" +?
??? "??? empId INTEGER PRIMARY KEY AUTOINCREMENT, " +?
??? "??? firstName TEXT, " +?
??? "??? lastName TEXT, " +?
??? "??? salary NUMERIC CHECK (salary > 0)" +?
??? ")";
???
?createStmt.text = sql;
?createStmt.execute();?
?
??Alert.show("成功完成");
?}
?catch(error:SQLError)
?{
??Alert.show(error.message);
??Alert.show(error.details);
?}
}??
?
代碼下載:
http://files.cnblogs.com/aierong/Air_Test_SQLite.rar
本章主要總結(jié)數(shù)據(jù)庫(kù)的插入,刪除,修改,以及語(yǔ)句參數(shù)的使用
本章提到的同步和異步操作,不明白的可以看上篇文章
http://www.cnblogs.com/aierong/archive/2009/01/22/flex_Sqlite_1.html
?
0.SQLStatement類(lèi)介紹
SQLStatement實(shí)例用于針對(duì)通過(guò) SQLConnection 實(shí)例打開(kāi)的本地 SQL 數(shù)據(jù)庫(kù)執(zhí)行 SQL 語(yǔ)句。
SQLStatement實(shí)例通過(guò)將 SQLConnection 實(shí)例設(shè)置為 SQLStatement 實(shí)例的 sqlConnection 屬性的值來(lái)鏈接到 SQLConnection 實(shí)例。
text
屬性用要執(zhí)行的
SQL
語(yǔ)句的實(shí)際文本進(jìn)行填充。如有必要,可以使用
parameters
屬性指定
SQL
語(yǔ)句參數(shù)的值,并通過(guò)調(diào)用
execute()
方法執(zhí)行該語(yǔ)句。
1.
插入數(shù)據(jù)
同步版本:
import mx.controls.Alert;
private var con:SQLConnection;
private function initApp():void
{
?var file:File = File.applicationStorageDirectory.resolvePath("myTestdb.db")
?
?con = new SQLConnection();
?var stmt:SQLStatement = new SQLStatement();
?
?try
?{
??con.open(file);
??
??stmt.sqlConnection = con;
??stmt.text="INSERT INTO emp (firstName, lastName, salary) VALUES ('f', 'l', 88)";
??stmt.execute();
?}
?catch(error:SQLError)
?{
??Alert.show(error.message);
??Alert.show(error.details);
?}
}
代碼說(shuō)明:
SQLStatement類(lèi)的實(shí)例用于針對(duì)通過(guò) SQLConnection 實(shí)例打開(kāi)的本地 SQL 數(shù)據(jù)庫(kù)執(zhí)行 SQL 語(yǔ)句
?
2.得到已插入行的數(shù)據(jù)庫(kù)生成的行標(biāo)識(shí)
得到自動(dòng)增長(zhǎng)列的行標(biāo)識(shí)數(shù)值
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = con;
stmt.text="INSERT INTO emp (firstName, lastName, salary) VALUES ('f', 'l', 88)";
stmt.execute();
?
var result:SQLResult = stmt.getResult();
var primaryKey:Number = result.lastInsertRowID;
???
Alert.show(primaryKey.toString());
代碼說(shuō)明:
SQLResult 類(lèi)提供對(duì)為響應(yīng) SQL 語(yǔ)句(SQLStatement 實(shí)例)執(zhí)行而返回的數(shù)據(jù)的訪(fǎng)問(wèn)
lastInsertRowID屬性:上次生成的行標(biāo)識(shí)符(由 SQL INSERT 語(yǔ)句生成),如果執(zhí)行的語(yǔ)句不是 INSERT 語(yǔ)句,則該值為 0。
?
3.
語(yǔ)句參數(shù)的使用
在多次使用一個(gè)
SQL
語(yǔ)句但該語(yǔ)句中的值不同的情況下,最佳方法是使用包括參數(shù)的
SQL
語(yǔ)句而不是在
SQL
文本中包括字面值。參數(shù)是語(yǔ)句文本中的一個(gè)占位符,每次執(zhí)行語(yǔ)句時(shí)都將它替換為實(shí)際的值。
參數(shù)名稱(chēng)由
“:”
或
“@”
字符后跟一個(gè)名稱(chēng)組成,例如:
:itemName? @firstName
還可以使用未命名參數(shù),使用
“?”
字符表示
SQL
語(yǔ)句中的參數(shù)。按照參數(shù)在語(yǔ)句中的順序,每個(gè)參數(shù)都分配有一個(gè)數(shù)字索引,數(shù)字索引從索引
0
(表示第一個(gè)參數(shù))開(kāi)始。
使用參數(shù)的優(yōu)點(diǎn)
:
1.
性能更佳
2.
顯式數(shù)據(jù)類(lèi)型指定
3.
安全性更高
實(shí)例代碼:得到自動(dòng)增長(zhǎng)列的行標(biāo)識(shí)數(shù)值(
異步版本
)
private var stmt1:SQLStatement;
private function GetlastInsertRowID():void
{
?stmt1 = new SQLStatement();
?stmt1.sqlConnection = con;
?
?stmt1.text="INSERT INTO emp (firstName, lastName, salary) VALUES (@firstName, @lastName, @salary)";
?stmt1.parameters["@firstName"]="f";
?stmt1.parameters["@lastName"]="l";
?stmt1.parameters["@salary"]=88;?
?
?stmt1.addEventListener(SQLEvent.RESULT,okHandler);
?stmt1.addEventListener(SQLErrorEvent.ERROR,errorHandler);
?stmt1.execute();
}
private function okHandler(evt:SQLEvent):void
{
?Alert.show("插入成功");
?var re:SQLResult= this.stmt1.getResult();
?var id:Number=re.lastInsertRowID;
?Alert.show(id.toString());
}
private function errorHandler(evt:SQLErrorEvent):void
{
?Alert.show("失敗");
?Alert.show(evt.error.message);
?Alert.show(evt.error.details);
}
代碼說(shuō)明:
此例題中用到了語(yǔ)句參數(shù)@firstName, @lastName, @salary,并分別賦值
要是使用未命名參數(shù),把代碼修改如下即可(注意數(shù)字索引從0開(kāi)始):
stmt1.text="INSERT INTO emp (firstName, lastName, salary) VALUES (?, ?, ?)";
stmt1.parameters[0]="f";
stmt1.parameters[1]="l";
stmt1.parameters[2]=88;
?
4.刪除操作
private function del():void
{
?var stmt:SQLStatement = new SQLStatement();
?stmt.sqlConnection = con;
?stmt.text="delete from emp where salary=:salary";
?stmt.parameters[":salary"]=88;
?stmt.execute();
?
?var result:SQLResult = stmt.getResult();
??? var count:Number = result.rowsAffected;
???
??? Alert.show("成功刪除"+count.toString()+"行");
}
代碼說(shuō)明:
rowsAffected屬性:指示受此操作影響的行數(shù)
請(qǐng)注意,當(dāng)相關(guān)的 SQL 操作為不帶 WHERE 子句的 DELETE 語(yǔ)句時(shí)(即該語(yǔ)句刪除表中的所有行),rowsAffected 屬性始終為 0,而不管刪除了多少行。如果您需要知道刪除的行數(shù),則可以包括 WHERE 子句 WHERE 1 = 1,在這種情況下,將刪除所有行,并且 rowsAffected 屬性會(huì)精確反映已刪除的行數(shù)
?
5.修改操作
private function updateData():void
{
?var stmt:SQLStatement = new SQLStatement();
?stmt.sqlConnection = con;
?stmt.text="update emp set lastName=:lastName where salary=:salary";
?stmt.parameters[":lastName"]="la";
?stmt.parameters[":salary"]=88;
?stmt.execute();
?
?var result:SQLResult = stmt.getResult();
??? var count:Number = result.rowsAffected;
???
??? Alert.show("成功修改"+count.toString()+"行");
}
代碼說(shuō)明:
把salary=88的lastName修改為"la"
?
6.代碼下載
http://files.cnblogs.com/aierong/Air_Test_SQLite2.rar
??
本章主要總結(jié)表的查詢(xún)
1.查詢(xún)
同步版本:
private function query():void
{
?var stmt:SQLStatement = new SQLStatement();
?stmt.sqlConnection = con;
??? ?stmt.text = "select empId,firstName,lastName,salary from emp";
?stmt.execute();?
?
?var result:SQLResult = stmt.getResult();
?
?if ( result.data!=null )
?{
??var numResults:int =result.data.length;
????
??for (var i:int = 0; i < numResults; i++)
??? ?{
??????? ?var row:Object = result.data[i];
??????? ?var output:String = "empId: " + row.empId;
??????? ?output += "; firstName: " + row.firstName;
??????? ?output += "; lastName: " + row.lastName;
??????? ?output += "; salary: " + row.salary;?
???????? ?
??????? ?Alert.show(output);?
???? }
??}
}
代碼說(shuō)明:
getResult ()方法:執(zhí)行結(jié)果的SQLResult對(duì)象的訪(fǎng)問(wèn)
SQLResult的data屬性:執(zhí)行語(yǔ)句而返回的數(shù)據(jù)。
如果某一語(yǔ)句不返回任何數(shù)據(jù),則此屬性為
null
。這就是本代碼需要判斷是否為空的目的。
2.
查詢(xún)部分結(jié)果
默認(rèn)情況下,執(zhí)行
SELECT
語(yǔ)句會(huì)一次檢索結(jié)果集的所有行,有時(shí)我們需要查詢(xún)第
1
行怎么辦?
查詢(xún)第
1
行的異步版本實(shí)例代碼如下:
private var responder:Responder;
private var stmt:SQLStatement;
private function querytop1():void
{
?stmt = new SQLStatement();
?stmt.sqlConnection = con;
?stmt.text = "select empId,firstName,lastName,salary from emp where firstName=:firstName";
??? ?stmt.parameters[":firstName"]="f";
??? ?responder= new Responder(resultHandler, errorHandler);
?stmt.execute(1,responder);?
}
private function resultHandler(result:SQLResult):void
{
?if ( result.data!=null )
?{
??var numResults:int =result.data.length;
????
??for (var i:int = 0; i < numResults; i++)
??? ?{
??????? ?var row:Object = result.data[i];
??????? ?var output:String = "empId: " + row.empId;
??????? ?output += "; firstName: " + row.firstName;
??????? ?output += "; lastName: " + row.lastName;
??????? ?output += "; salary: " + row.salary;?
???????? ?
??????? ?Alert.show(output);?
???? }
??}
}
private function errorHandler(error:SQLError):void
{
?Alert.show(error.message);
?Alert.show(error.details);
}
代碼說(shuō)明:
execute () 方法參數(shù)說(shuō)明:
第1個(gè)參數(shù):此值指示該語(yǔ)句一次返回的行數(shù)。
默認(rèn)值為
-1
,指示一次返回所有結(jié)果行,
第
2
個(gè)參數(shù):一個(gè)
Responder
對(duì)象,指定操作成功或失敗時(shí)要調(diào)用的方法。
實(shí)際在本例中,也可以不用Responder對(duì)象,而用事件偵聽(tīng)器執(zhí)行SQLStatement,以確定語(yǔ)句的執(zhí)行何時(shí)完成或失敗
stmt.addEventListener(SQLEvent.RESULT,resultHandler);
stmt.addEventListener(SQLErrorEvent.ERROR,errorHandler);
具體代碼實(shí)現(xiàn)可以參照以前的文章
?
3.代碼下載
http://files.cnblogs.com/aierong/Air_Test_SQLite3.rar
本章主要總結(jié)數(shù)據(jù)操作中的事務(wù)控制
由于SQLite中SQL語(yǔ)句不支持事務(wù),我們可以通過(guò)SQLConnection類(lèi)的與事務(wù)相關(guān)的方法可使用此功能:SQLConnection.begin()、SQLConnection.commit() 和 SQLConnection.rollback()來(lái)實(shí)現(xiàn)事務(wù)功能。
關(guān)于air本地?cái)?shù)據(jù)庫(kù)中的SQL支持可以參考
http://help.adobe.com/zh_CN/AIR/1.5/jslr/index.html?localDatabaseSQLSupport.html
事務(wù)實(shí)例代碼:
import mx.controls.Alert;
private var con:SQLConnection;
private function initApp():void
{
?var file:File = File.applicationStorageDirectory.resolvePath("myTestdb.db")
?con = new SQLConnection();
?var stmt:SQLStatement = new SQLStatement();
?
?? try
?? {
?? ?con.open(file);
?? ?
?? ?con.begin();
?? ?stmt.sqlConnection=con;
?? ?stmt.text="INSERT INTO emp (firstName, lastName, salary) VALUES ('f', 'l', 1110)";
??stmt.execute();
?? ?con.commit(); ?
?? }
?? catch(err:SQLError)
?? {
?? ?con.rollback();
?? ?Alert.show(err.message);
?? }
}?
代碼說(shuō)明:
事務(wù)由begin方法開(kāi)始,其間運(yùn)行的n個(gè)sql語(yǔ)句要是成功,就由commit方法提交,其間要是有任何一個(gè)sql語(yǔ)句發(fā)生錯(cuò)誤,就由rollback方法全部回滾.代碼比較簡(jiǎn)單,有其他語(yǔ)言開(kāi)發(fā)建議的人一眼就可以看明白。
?
代碼下載:
http://files.cnblogs.com/aierong/Air_Test_SQLite4.rar
A.Flex Air開(kāi)發(fā)SQLite小結(jié)
1.sqlite各語(yǔ)句間用分號(hào)間隔
例如:select * from tablea;select * from tableb;
2.
關(guān)于
Flex
中用一個(gè)
SQLStatement
執(zhí)行多條
SQL
的代碼的問(wèn)題
有些時(shí)候我們可能一次執(zhí)行多條
SQL
,不過(guò)比較遺憾的是一個(gè)
SQLStatement
只會(huì)執(zhí)行第一個(gè)
SQL
。
下面是一段簡(jiǎn)單的代碼可以幫你解決這個(gè)問(wèn)題,不過(guò)需要在
SQL
件用
’;'
劃分:
try {
????? // Separate all statements
?????? var parts:Array = createSQL.split( ');' );
????? for( var i:int; i<parts.length; i++ ) {
???????? // Only, if we really have an SQL statement
???????? if ( '' != parts[i] ) {
???????????? createStmt.text = parts[i] + ');';
???????????? createStmt.execute();??
???????? }
????? }??
?? } catch( error:SQLError ) {
?????? // something failed...
?? }
具體文章可以
看
?
B.SQLite
開(kāi)發(fā)工具
SQLite Spy
http://www.yunqa.de/delphi/sqlitespy
一個(gè)非常不錯(cuò)的SQLite Database Explorer and Query Analyzer。不需要安裝。
強(qiáng)烈推薦這個(gè),我自己也用
.
?
DBTools Manager
有免費(fèi)版本的多數(shù)據(jù)庫(kù)管理器,同時(shí)支持SQLite
?
Aqua Data Studio
有很多功能支持很多數(shù)據(jù)庫(kù)的一個(gè)軟件,可以通過(guò)
JDBC
或
ODBC
來(lái)支持
SQLite
查詢(xún)。
?
還有SQLite Administrator,后來(lái)發(fā)現(xiàn)Firefox的插件(addons) Sqlite Manager也是不錯(cuò)的選擇。
?
C.SQLite與Sql Server的語(yǔ)法差異
1.返回最后插入的標(biāo)識(shí)值
返回最后插入的標(biāo)識(shí)值sql server用@@IDENTITY
sqlite用標(biāo)量函數(shù)LAST_INSERT_ROWID()
返回通過(guò)當(dāng)前的 SQLConnection 插入到數(shù)據(jù)庫(kù)的最后一行的行標(biāo)識(shí)符(生成的主鍵)。此值與 SQLConnection.lastInsertRowID 屬性返回的值相同。
2.top n
在sql server中返回前2行可以這樣:
select top 2 * from aa
order by ids desc
sqlite中用LIMIT,語(yǔ)句如下:
select * from aa
order by ids desc
LIMIT 2
3.GETDATE ( )
在sql server中GETDATE ( )返回當(dāng)前系統(tǒng)日期和時(shí)間
sqlite中沒(méi)有
4.EXISTS語(yǔ)句
sql server中判斷插入(不存在ids=5的就插入)
IF NOT EXISTS (select * from aa where ids=5)
BEGIN
insert into aa(nickname)
select 't'
END
在sqlite中可以這樣
insert into aa(nickname)
select 't'
where not exists(select * from aa where ids=5)
5.
嵌套事務(wù)
sqlite
僅允許單個(gè)活動(dòng)的事務(wù)
6.RIGHT 和 FULL OUTER JOIN
sqlite不支持 RIGHT OUTER JOIN 或 FULL OUTER JOIN
7.
可更新的視圖
sqlite
視圖是只讀的。不能對(duì)視圖執(zhí)行
DELETE
、
INSERT
或
UPDATE
語(yǔ)句,
sql server
是可以對(duì)視圖
DELETE
、
INSERT
或
UPDATE
?
最后推薦幾個(gè)好站點(diǎn)對(duì)開(kāi)發(fā)
sqlite
有幫助:
sqlite
官方站
?
http://www.sqlite.org/lang.html
?
sqlite中文站
?
Adobe AIR 包括創(chuàng)建和使用本地 SQL 數(shù)據(jù)庫(kù)的功能
http://help.adobe.com/zh_CN/AIR/1.5/devappshtml/WS5b3ccc516d4fbf351e63e3d118676a5497-7fb4.html
?
Adobe AIR 語(yǔ)言參考本地?cái)?shù)據(jù)庫(kù)中的 SQL 支持
http://help.adobe.com/zh_CN/AIR/1.5/jslr/index.html?localDatabaseSQLSupport.html
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
