從資料庫擷取資料

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」。針對結果集中的每一個列,會使用名稱 itemIditemNameprice 的屬性建立 Object 實體。這些屬性包含其對應欄的值。

下面列出的程式碼會定義文字是 SELECT 陳述式的 SQLStatement 實體。陳述式所擷取的列會包含命名為 employees 的資料表中所有列的 firstNamelastName 欄值。此範例會使用非同步執行模式。當執行完成之後,就會呼叫 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 的資料表中所有列的 firstNamelastName 欄值。結果資料列會使用 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() 方法的說明。