Pobieranie danych z bazy danych

Adobe AIR 1.0 i starsze wersje

Pobieranie danych z bazy danych jest procesem dwuetapowym. Najpierw należy wykonać instrukcję SQL SELECT , opisując zestaw danych żądany z bazy danych. Następnie należy uzyskać dostęp do pobranych danych i wyświetlić lub zmodyfikować je zgodnie z potrzebami.

Wykonywanie instrukcji SELECT

W celu pobrania istniejących danych z bazy danych należy skorzystać z instancji klasy SQLStatement . Przypisz odpowiednią instrukcję SQL SELECT do właściwości text wystąpienia, a następnie wywołaj metodę execute() wystąpienia.

Szczegółowe informacje o składni instrukcji SELECT zawiera sekcja Obsługa języka SQL w lokalnych bazach danych .

W poniższym przykładzie przedstawiono wykonanie instrukcji SELECT w celu uzyskania danych z tabeli o nazwie „products” w przypadku używania trybu wykonywania asynchronicznego.

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>

Poniższy przykład prezentuje wykonanie instrukcji SELECT w celu uzyskania danych z tabeli o nazwie „products” przy wykorzystaniu trybu wykonania synchronicznego:

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>

Gdy kończy się wykonanie instrukcji w trybie wykonywania asynchronicznego, instrukcja SQLStatement wywołuje zdarzenie result ( SQLEvent.RESULT ), co oznacza pomyślne wykonanie instrukcji. Z kolei jeśli obiekt Responder zostanie przekazany jako argument w wywołaniu metody execute() , wówczas następuje wywołanie funkcji obsługi wyniku obiektu Responder. W trybie wykonywania asynchronicznego wykonywanie zostaje wstrzymane do czasu zakończenia operacji execute() — następnie jest kontynuowane od kolejnego wiersza kodu.

Dostęp do danych wynikowych instrukcji SELECT

Po zakończeniu wykonywania instrukcji SELECT kolejnym krokiem jest uzyskanie dostępu do pobranych danych. W celu pobrania danych wynikowych wykonanej instrukcji SELECT należy wywołać metodę getResult() obiektu SQLStatement:

var result:SQLResult = selectStatement.getResult();

Metoda getResult() zwraca obiekt SQLResult . Właściwość data obiektu SQLResult jest obiektem Array zawierającym wyniki wykonania instrukcji 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]; 
}

Każdy wiersz danych w zestawie wynikowym instrukcji SELECT staje się instancją klasy Object zawartą w tablicy (obiekcie Array) data . Ten obiekt zawiera właściwości, których nazwy są zgodne z nazwami kolumn w zestawie wynikowym. Właściwości zawierają wartości z kolumn zestawu wynikowego. Przykład: załóżmy, że instrukcja SELECT określa zestaw wynikowy z trzema kolumnami o nazwach „itemId”, „itemName” i „price”. Dla każdego wiersza w zestawie wynikowym tworzona jest instancja Object z właściwościami o nazwach itemId , itemName i price . Te właściwości zawierają wartości z odpowiadających im kolumn.

Poniższy fragment kodu definiuje instancję SQLStatement, której tekst jest instrukcją SELECT . Instrukcja pobiera wiersze zawierające wartości kolumn firstName i lastName ze wszystkich wierszy tabeli o nazwie employees . W tym przykładzie prezentowany jest tryb wykonania asynchronicznego. Po zakończeniu wykonywania następuje wywołanie metody selectResult() , a dostęp do wierszy wynikowych jest uzyskiwany za pomocą metody SQLStatement.getResult() . Dane wynikowe są wyświetlane za pomocą metody trace() . W tym przykładzie przyjęto, że istnieje instancja SQLConnection o nazwie conn , która jest już połączona z bazą danych. Założono również, że tabela „pracownicy” została utworzona i zapełniona danymi.

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>

Poniższy fragment kodu prezentuje techniki podobne do poprzedniego fragmentu, ale w tym fragmencie zastosowano tryb wykonania synchronicznego. W przykładzie zdefiniowano instancję klasy SQLStatement , której tekstem jest instrukcja SELECT . Instrukcja pobiera wiersze zawierające wartości kolumn firstName i lastName z wszystkich wierszy tabeli o nazwie employees . Dostęp do wierszy wynikowych jest uzyskiwany za pomocą metody SQLStatement.getResult() . Dane wynikowe są wyświetlane za pomocą metody trace() . W tym przykładzie przyjęto, że istnieje instancja SQLConnection o nazwie conn , która jest już połączona z bazą danych. Założono również, że tabela „pracownicy” została utworzona i zapełniona danymi.

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>

Definiowanie typu danych wynikowych instrukcji SELECT

Domyślnie każdy wiersz zwracany przez instrukcję SELECT jest tworzony jako wystąpienie klasy Object, w którym właściwości mają nazwy takie same jak kolumny zestawu wynikowego, a wartości w poszczególnych kolumnach są wartościami właściwości skojarzonych z tymi kolumnami. Jednak przed wykonaniem instrukcji SQL SELECT można ustawić właściwość itemClass wystąpienia klasy SQLStatement na klasę. Na skutek ustawienia właściwości itemClass każdy wiersz zwracany przez instrukcję SELECT jest tworzony jako instancja wyznaczonej klasy. Środowisko wykonawcze przypisuje wartości kolumn wynikowych do wartości właściwości poprzez dopasowanie nazw kolumn z zestawu wynikowego SELECT z nazwami właściwości z klasy itemClass .

Każda klasa przypisana jako wartość właściwości itemClass musi zawierać konstruktor, który nie wymaga żadnych parametrów. Ponadto klasa musi mieć pojedynczą właściwość dla każdej kolumny zwróconej przez instrukcję SELECT . Jeśli nazwie kolumny z listy SELECT nie odpowiada nazwa właściwości w klasie itemClass , jest to traktowane jako błąd.

Uzyskiwanie wyników SELECT w częściach

Domyślnie wykonanie instrukcji SELECT powoduje pobranie wszystkich wierszy w postaci zestawu wynikowego jednocześnie. Po wykonaniu instrukcji zwykle następuje przetworzenie danych wynikowych, np. tworzenie obiektów lub wyświetlanie danych na ekranie. Jeśli instrukcja zwróci dużą liczbę wierszy, przetwarzanie wszystkich danych jednocześnie może bardzo obciążać komputer, co może powodować problemy z odświeżaniem interfejsu użytkownika.

Istnieje możliwość zwiększenia subiektywnej wydajności aplikacji poprzez zdefiniowanie instrukcji dla środowiska wykonawczego dotyczącej zwrócenia określonej liczby wierszy jednocześnie. Zdefiniowanie takiej instrukcji może spowodować szybsze zwrócenie pierwszego zestawu wynikowego. Umożliwia także podział wierszy wyników na zestawy, dzięki czemu interfejs użytkownika zostaje zaktualizowany po przetworzeniu każdego zestawu wierszy. Stosowanie tej techniki jest zalecane wyłącznie w przypadku trybu wykonania asynchronicznego.

W celu uzyskania wyników instrukcji SELECT w częściach należy określić wartość pierwszego parametru metody SQLStatement.execute() (parametr prefetch ). Parametr prefetch określa liczbę wierszy do pobrania przy pierwszym wykonaniu instrukcji. Po wywołaniu metody execute() klasy SQLStatement należy określić wartość parametru prefetch — ta wartość będzie określała liczbę wierszy do pobrania:

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 

Instrukcja wywołuje zdarzenie result , co oznacza, że pierwszy zestaw wierszy wynikowych jest już dostępny. Wynikowa właściwość data instancji klasy SQLResult zawiera wiersze danych, a właściwość complete wskazuje, czy istnieją dodatkowe wiersze do pobrania. W celu pobrania dodatkowych wierszy wyników należy wywołać metodę next() klasy SQLStatement. Pierwszy parametr metody next() — podobnie jak w przypadku metody execute() — określa liczbę wierszy pobieranych przy następnym wywołaniu zdarzenia 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); 
        } 
    } 
} 

Klasa SQLStatement wywołuje zdarzenie result za każdym razem, gdy metoda next() zwraca kolejny zestaw wierszy wynikowych. W konsekwencji ta sama funkcja detektora może służyć do dalszego przetwarzania wyników (wywołań metody next() ) do czasu pobrania wszystkich wierszy.

Więcej informacji zawierają opisy metody SQLStatement.execute() (opis parametru prefetch ) oraz metody SQLStatement.next() .