從資料庫擷取資料

Adobe AIR 1.0 以及更新的版本

從資料庫擷取資料包含兩個步驟。首先,您必須執行 SQL SELECT 陳述式,描述要從資料庫擷取的資料集。然後,您要存取已擷取的資料,並視應用程式所需來顯示或操控。

執行 SELECT 陳述式

若要從資料庫擷取現有資料,請使用 SQLStatement 實體。將適當的 SQL SELECT 陳述式指定給實體的 text 屬性,然後呼叫其 execute() 方法。

如需 SELECT 陳述式語法的詳細資訊,請參閱 本機資料庫內的 SQL 支援

下列範例會示範如何使用非同步執行模式,執行 SELECT 陳述式,從名稱為「products」的資料表中擷取資料:

var selectStmt:SQLStatement = new SQLStatement(); 
     
// A SQLConnection named "conn" has been created previously 
selectStmt.sqlConnection = conn; 
     
selectStmt.text = "SELECT itemId, itemName, price FROM products"; 
     
selectStmt.addEventListener(SQLEvent.RESULT, resultHandler); 
selectStmt.addEventListener(SQLErrorEvent.ERROR, errorHandler); 
     
selectStmt.execute(); 
     
function resultHandler(event:SQLEvent):void 
{ 
    var result:SQLResult = selectStmt.getResult(); 
     
    var numResults:int = result.data.length; 
    for (var i:int = 0; i < numResults; i++) 
    { 
        var row:Object = result.data[i]; 
        var output:String = "itemId: " + row.itemId; 
        output += "; itemName: " + row.itemName; 
        output += "; price: " + row.price; 
        trace(output); 
    } 
} 
     
function errorHandler(event:SQLErrorEvent):void 
{ 
    // Information about the error is available in the 
    // event.error property, which is an instance of  
    // the SQLError class. 
}
<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()"> 
    <mx:Script> 
        <![CDATA[ 
            import flash.data.SQLConnection; 
            import flash.data.SQLResult; 
            import flash.data.SQLStatement; 
            import flash.errors.SQLError; 
            import flash.events.SQLErrorEvent; 
            import flash.events.SQLEvent; 
             
            private function init():void 
            { 
                var selectStmt:SQLStatement = new SQLStatement(); 
                 
                // A SQLConnection named "conn" has been created previously 
                selectStmt.sqlConnection = conn; 
                 
                selectStmt.text = "SELECT itemId, itemName, price FROM products"; 
                 
                selectStmt.addEventListener(SQLEvent.RESULT, resultHandler); 
                selectStmt.addEventListener(SQLErrorEvent.ERROR, errorHandler); 
                 
                selectStmt.execute(); 
            } 
             
            private function resultHandler(event:SQLEvent):void 
            { 
                var result:SQLResult = selectStmt.getResult(); 
                 
                var numResults:int = result.data.length; 
                for (var i:int = 0; i < numResults; i++) 
                { 
                    var row:Object = result.data[i]; 
                    var output:String = "itemId: " + row.itemId; 
                    output += "; itemName: " + row.itemName; 
                    output += "; price: " + row.price; 
                    trace(output); 
                } 
            } 
             
            private function errorHandler(event:SQLErrorEvent):void 
            { 
                // Information about the error is available in the 
                // event.error property, which is an instance of  
                // the SQLError class. 
            } 
        ]]> 
    </mx:Script> 
</mx:WindowedApplication>

下列範例會示範如何使用同步執行模式,執行 SELECT 陳述式,從名稱為「products」的資料表中擷取資料:

var selectStmt:SQLStatement = new SQLStatement(); 
     
// A SQLConnection named "conn" has been created previously 
selectStmt.sqlConnection = conn; 
     
selectStmt.text = "SELECT itemId, itemName, price FROM products"; 
     
try 
{ 
    selectStmt.execute(); 
     
    var result:SQLResult = selectStmt.getResult(); 
     
    var numResults:int = result.data.length; 
    for (var i:int = 0; i < numResults; i++) 
    { 
        var row:Object = result.data[i]; 
        var output:String = "itemId: " + row.itemId; 
        output += "; itemName: " + row.itemName; 
        output += "; price: " + row.price; 
        trace(output); 
    } 
} 
catch (error:SQLError) 
{ 
    // Information about the error is available in the 
    // error variable, which is an instance of  
    // the SQLError class. 
}
<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()"> 
    <mx:Script> 
        <![CDATA[ 
            import flash.data.SQLConnection; 
            import flash.data.SQLResult; 
            import flash.data.SQLStatement; 
            import flash.errors.SQLError; 
            import flash.events.SQLErrorEvent; 
            import flash.events.SQLEvent; 
             
            private function init():void 
            { 
                var selectStmt:SQLStatement = new SQLStatement(); 
                 
                // A SQLConnection named "conn" has been created previously 
                selectStmt.sqlConnection = conn; 
                 
                selectStmt.text = "SELECT itemId, itemName, price FROM products"; 
                 
                try 
                { 
                    selectStmt.execute(); 
                     
                    var result:SQLResult = selectStmt.getResult(); 
                     
                    var numResults:int = result.data.length; 
                    for (var i:int = 0; i < numResults; i++) 
                    { 
                        var row:Object = result.data[i]; 
                        var output:String = "itemId: " + row.itemId; 
                        output += "; itemName: " + row.itemName; 
                        output += "; price: " + row.price; 
                        trace(output); 
                    } 
                } 
                catch (error:SQLError) 
                { 
                    // Information about the error is available in the 
                    // error variable, which is an instance of  
                    // the SQLError class. 
                } 
            } 
        ]]> 
    </mx:Script> 
</mx:WindowedApplication>

在非同步執行模式中,當陳述式完成執行時,SQLStatement 實體會傳送 result 事件 ( SQLEvent.RESULT ) 指出已成功地執行該陳述式。或者,如果傳遞 Responder 物件做為 execute() 方法的引數,就會呼叫 Responder 物件的結果處理常式函數。在同步執行模式中,執行程序會暫停至 execute() 作業完成後,再繼續執行下一行程式碼。

存取 SELECT 陳述式結果資料

SELECT 陳述式完成執行後,下一個步驟就是存取已擷取的資料。您可以呼叫 SQL 陳述式的 getResult() 方法來執行 SELECT 陳述式,這樣就可以擷取結果:

var result:SQLResult = selectStatement.getResult();

getResult() 方法會傳回 SQLResult 物件。SQLResult 物件的 data 屬性是 Array,其中包含 SELECT 陳述式的結果:

var numResults:int = result.data.length; 
for (var i:int = 0; i < numResults; i++) 
{ 
    // row is an Object representing one row of result data 
    var row:Object = result.data[i]; 
}

SELECT 結果集的每個資料列會是 Object 實體 (包含於 data Array)。 該物件具備的屬性,其名稱會與結果集的欄名稱相符。屬性中會包含結果集各欄的值。例如,假設 SELECT 陳述式指定有三個欄的結果集,而欄的名稱分別為「itemId」、「itemName」和「price」。針對結果集中的每一個列,會使用名稱 itemId itemName price 的屬性建立 Object 實體。這些屬性包含其對應欄的值。

下面列出的程式碼會定義文字是 SELECT 陳述式的 SQLStatement 實體。陳述式所擷取的列會包含命名為 employees 的資料表中所有列的 firstName lastName 欄值。此範例會使用非同步執行模式。當執行完成之後,就會呼叫 selectResult() 方法,並使用 SQLStatement.getResult() 存取結果資料列,然後使用 trace() 方法顯示。請注意,此程式碼範例假設已有一個實體化且連線至資料庫的 SQLConnection 實體 conn 。它也假設「employees」資料表已建立並填入資料。

import flash.data.SQLConnection; 
import flash.data.SQLResult; 
import flash.data.SQLStatement; 
import flash.events.SQLErrorEvent; 
import flash.events.SQLEvent; 
     
// ... create and open the SQLConnection instance named conn ... 
     
// create the SQL statement 
var selectStmt:SQLStatement = new SQLStatement(); 
selectStmt.sqlConnection = conn; 
     
// define the SQL text 
var sql:String =  
    "SELECT firstName, lastName " +  
    "FROM employees"; 
selectStmt.text = sql; 
     
// register listeners for the result and error events 
selectStmt.addEventListener(SQLEvent.RESULT, selectResult); 
selectStmt.addEventListener(SQLErrorEvent.ERROR, selectError); 
     
// execute the statement 
selectStmt.execute(); 
     
function selectResult(event:SQLEvent):void 
{ 
    // access the result data 
    var result:SQLResult = selectStmt.getResult(); 
     
    var numRows:int = result.data.length; 
    for (var i:int = 0; i < numRows; i++) 
    { 
        var output:String = ""; 
        for (var columnName:String in result.data[i]) 
        { 
            output += columnName + ": " + result.data[i][columnName] + "; "; 
        } 
        trace("row[" + i.toString() + "]\t", output); 
    } 
} 
     
function selectError(event:SQLErrorEvent):void 
{ 
    trace("Error message:", event.error.message); 
    trace("Details:", event.error.details); 
} 
<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()"> 
    <mx:Script> 
        <![CDATA[ 
            import flash.data.SQLConnection; 
            import flash.data.SQLResult; 
            import flash.data.SQLStatement; 
            import flash.events.SQLErrorEvent; 
            import flash.events.SQLEvent; 
             
            private function init():void 
            { 
                // ... create and open the SQLConnection instance named conn ... 
                 
                // create the SQL statement 
                var selectStmt:SQLStatement = new SQLStatement(); 
                selectStmt.sqlConnection = conn; 
                 
                // define the SQL text 
                var sql:String =  
                    "SELECT firstName, lastName " +  
                    "FROM employees"; 
                selectStmt.text = sql; 
                 
                // register listeners for the result and error events 
                selectStmt.addEventListener(SQLEvent.RESULT, selectResult); 
                selectStmt.addEventListener(SQLErrorEvent.ERROR, selectError); 
                 
                // execute the statement 
                selectStmt.execute(); 
            } 
             
            private function selectResult(event:SQLEvent):void 
            { 
                // access the result data 
                var result:SQLResult = selectStmt.getResult(); 
                 
                var numRows:int = result.data.length; 
                for (var i:int = 0; i < numRows; i++) 
                { 
                    var output:String = ""; 
                    for (var columnName:String in result.data[i]) 
                    { 
                        output += columnName + ": " + result.data[i][columnName] + "; "; 
                    } 
                    trace("row[" + i.toString() + "]\t", output); 
                } 
            } 
             
            private function selectError(event:SQLErrorEvent):void 
            { 
                trace("Error message:", event.error.message); 
                trace("Details:", event.error.details); 
            } 
        ]]> 
    </mx:Script> 
</mx:WindowedApplication>

下面列出的程式碼會示範與上一個範例相同的技巧,但使用同步執行模式。此範例會定義文字是 SELECT 陳述式的 SQLStatement 實體。陳述式所擷取的列會包含命名為 employees 的資料表中所有列的 firstName lastName 欄值。結果資料列會使用 SQLStatement.getResult() 存取,並使用 trace() 方法顯示。請注意,此程式碼範例假設已有一個實體化且連線至資料庫的 SQLConnection 實體 conn 。它也假設「employees」資料表已建立並填入資料。

import flash.data.SQLConnection; 
import flash.data.SQLResult; 
import flash.data.SQLStatement; 
import flash.errors.SQLError; 
     
// ... create and open the SQLConnection instance named conn ... 
     
// create the SQL statement 
var selectStmt:SQLStatement = new SQLStatement(); 
selectStmt.sqlConnection = conn; 
     
// define the SQL text 
var sql:String =  
    "SELECT firstName, lastName " +  
    "FROM employees"; 
selectStmt.text = sql; 
     
try 
{ 
    // execute the statement 
    selectStmt.execute(); 
     
    // access the result data 
    var result:SQLResult = selectStmt.getResult(); 
     
    var numRows:int = result.data.length; 
    for (var i:int = 0; i < numRows; i++) 
    { 
        var output:String = ""; 
        for (var columnName:String in result.data[i]) 
        { 
            output += columnName + ": " + result.data[i][columnName] + "; "; 
        } 
        trace("row[" + i.toString() + "]\t", output); 
    } 
} 
catch (error:SQLError) 
{ 
    trace("Error message:", error.message); 
    trace("Details:", error.details); 
} 
<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()"> 
    <mx:Script> 
        <![CDATA[ 
            import flash.data.SQLConnection; 
            import flash.data.SQLResult; 
            import flash.data.SQLStatement; 
            import flash.errors.SQLError; 
             
            private function init():void 
            { 
                // ... create and open the SQLConnection instance named conn ... 
                 
                // create the SQL statement 
                var selectStmt:SQLStatement = new SQLStatement(); 
                selectStmt.sqlConnection = conn; 
                 
                // define the SQL text 
                var sql:String =  
                    "SELECT firstName, lastName " +  
                    "FROM employees"; 
                selectStmt.text = sql; 
                 
                try 
                { 
                    // execute the statement 
                    selectStmt.execute(); 
                     
                    // access the result data 
                    var result:SQLResult = selectStmt.getResult(); 
                     
                    var numRows:int = result.data.length; 
                    for (var i:int = 0; i < numRows; i++) 
                    { 
                        var output:String = ""; 
                        for (var columnName:String in result.data[i]) 
                        { 
                            output += columnName + ": "; 
                            output += result.data[i][columnName] + "; "; 
                        } 
                        trace("row[" + i.toString() + "]\t", output); 
                    } 
                } 
                catch (error:SQLError) 
                { 
                    trace("Error message:", error.message); 
                    trace("Details:", error.details); 
                } 
            } 
        ]]> 
    </mx:Script> 
</mx:WindowedApplication>

定義 SELECT 結果資料的資料類型

根據預設,由 SELECT 陳述式傳回的每列都會建立為 Object 實體,其屬性名稱會使用結果集之欄名稱來命名,而每個欄的值會做為其關聯陣列的值。但是,在執行 SQL SELECT 陳述式之前,您可以將 SQLStatement 實體的 itemClass 屬性設定為類別。 http://help.adobe.com/zh_TW/Flash/CS5/AS3LR/flash/data/SQLStatement.html 透過設定 itemClass 屬性,由 SELECT 陳述式傳回的每列都會建立為指定類別的實體。執行階段會透過讓 SELECT 結果集中的欄名稱與 itemClass 類別中的屬性名稱相符,將結果欄值指定為屬性值。

指定為 itemClass 屬性值的任何類別都必須具有不需要任何參數的建構函式。此外,對於 SELECT 陳述式傳回的每一欄,此類別還必須包含單一屬性。如果 SELECT 清單中某一欄的屬性名稱與 itemClass 類別中的屬性名稱不符,就會被視為錯誤。

擷取部分 SELECT 結果

根據預設,執行 SELECT 陳述式會一次擷取結果集中的所有列。一旦陳述式完成之後,通常會以某種方式處理已擷取的資料,例如建立物件或在螢幕上顯示資料。如果陳述式傳回很多列,一次處理所有資料會對電腦產生極大需求,進而造成使用者介面無法重新繪製。

您可以指示執行階段一次傳回特定數目的結果列,以顯著改進應用程式效能。這種作業方式可讓起始結果資料更快速傳回。同時,也能讓您將結果列分成多組,以便讓使用者在處理完每組列之後更新。請注意,這種技巧只有在非同步執行中才會有實際效用。

若要分批擷取 SELECT 結果,請為 SQLStatement.execute() 方法第一個參數 ( prefetch 參數) 指定值。 prefetch 參數會指出第一次執行陳述式時要擷取的列數。當您呼叫 SQLStatement 實體的 execute() 方法時,便會視您指定的 prefetch 參數值,來擷取該數目的列:

var stmt:SQLStatement = new SQLStatement(); 
stmt.sqlConnection = conn; 
     
stmt.text = "SELECT ..."; 
     
stmt.addEventListener(SQLEvent.RESULT, selectResult); 
     
stmt.execute(20); // only the first 20 rows (or fewer) are returned 

陳述式會傳送 result 事件,指出可使用第一組結果列。結果 SQLResult 實體的 data 屬性會包含資料列,而且其 complete 屬性會指出還有其它結果列仍待擷取。若要擷取其它結果列,請呼叫 SQLStatement 實體的 next() 方法。就像 execute() 方法一樣, next() 方法的第一個參數會用來指出下一次傳送 result 事件時所要擷取的列數。

function selectResult(event:SQLEvent):void 
{ 
    var result:SQLResult = stmt.getResult(); 
    if (result.data != null) 
    { 
        // ... loop through the rows or perform other processing ... 
         
        if (!result.complete) 
        { 
            stmt.next(20); // retrieve the next 20 rows 
        } 
        else 
        { 
            stmt.removeEventListener(SQLEvent.RESULT, selectResult); 
        } 
    } 
} 

每次 next() 方法傳回下一組結果列時,SQLStatement 都會傳送 result 事件。如此一來,相同的偵聽程式就可以繼續處理 (來自 next() 呼叫的) 結果,直到擷取所有列為止。

如需詳細資訊,請參閱有關 SQLStatement.execute() 方法 ( prefetch 參數說明) 和 SQLStatement.next() 方法的說明。