Recupero dei dati da un database

Adobe AIR 1.0 e versioni successive

Il recupero dei dati da un database si svolge in due fasi. Per prima cosa si esegue l'istruzione SQL SELECT descrivendo il set di dati che si desidera trovare nel database. Successivamente si accede ai dati recuperati e li si visualizza o manipola secondo le esigenze dell'applicazione in uso.

Esecuzione dell'istruzione SELECT

Per recuperare da un database i dati già esistenti utilizzate un'istanza SQLStatement. Assegnate l'istruzione SQL SELECT appropriata alla proprietà text dell'istanza, quindi chiamate il relativo metodo execute().

Per informazioni dettagliate sulla sintassi dell'istruzione SELECT, vedete Supporto di SQL nei database locali.

L'esempio seguente illustra l'esecuzione di un'istruzione SELECT al fine di recuperare dati da una tabella denominata “products” facendo uso della modalità di esecuzione asincrona.

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>

L'esempio seguente illustra l'esecuzione di un'istruzione SELECT al fine di recuperare dati da una tabella denominata “products” facendo uso della modalità di esecuzione sincrona.

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>

In tale modalità, quando un'istruzione finisce di essere eseguita, l'istanza SQLStatement genera un evento result (SQLEvent.RESULT) che indica la corretta esecuzione dell'istruzione in oggetto. In alternativa, se si passa un oggetto Responder come argomento nella chiamata execute(), viene chiamata la funzione gestore evento risultato dell'oggetto Responder. Nella modalità di esecuzione sincrona l'esecuzione si ferma finché l'operazione execute() non viene completata e passa poi alla linea successiva del codice.

Accesso ai dati risultanti dall'uso dell'istruzione SELECT

Una volta terminata l'esecuzione dell'istruzione SELECT, il passo successivo è l'accesso ai dati in tal modo recuperati. Per recuperare i dati risultati dall'esecuzione dell'istruzione SELECT, chiamate il metodo getResult() dell'oggetto SQLStatement:

var result:SQLResult = selectStatement.getResult();

Il metodo getResult() restituisce un oggetto SQLResult. La proprietà data dell'oggetto SQLResult è un array contenente i risultati dell'istruzione 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]; 
}

Ogni riga di dati nel set di risultati SELECT diventa un'istanza Object contenuta nell'array data. Tale oggetto ha proprietà i cui nomi corrispondono ai nomi delle colonne del set di risultati. Le proprietà, a loro volta, contengono i valori provenienti dalle colonne del set di risultati. Ad esempio, supponiamo che l'istruzione SELECT specifichi un set di risultati con tre colonne denominate “itemId”, “itemName” e “price”. Per ciascuna riga del set di risultati viene creata un'istanza Object con proprietà denominate itemId, itemName e price. Le proprietà contengono i valori provenienti dalle rispettive colonne.

Il seguente elenco di codici definisce un'istanza SQLStatement il cui testo è l'istruzione SELECT. L'istruzione recupera righe che contengono i valori delle colonne firstName e lastName di tutte le righe della tabella denominata employees. Questo esempio utilizza la modalità di esecuzione asincrona. Quando l'esecuzione è stata completata viene chiamato il metodo selectResult(); si accede alle righe di dati risultanti tramite SQLStatement.getResult() e le si visualizza usando il metodo trace(). Tenete presente che questo elenco presuppone che esista un'istanza SQLConnection denominata conn già attivata e connessa al database. Presuppone inoltre che la tabella “employees” sia già stata creata e che vi siano stati inseriti dati.

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>

L'elenco di codici seguente illustra le stesse tecniche dell'esempio precedente ma utilizza la modalità di esecuzione sincrona. L'esempio definisce un'istanza SQLStatement il cui testo è l'istruzione SELECT. L'istruzione recupera righe che contengono i valori delle colonne firstName e lastName di tutte le righe della tabella denominata employees. Si accede alle righe di dati risultanti tramite SQLStatement.getResult() e le si visualizza usando il metodo trace(). Tenete presente che questo elenco presuppone che esista un'istanza SQLConnection denominata conn già attivata e connessa al database. Presuppone inoltre che la tabella “employees” sia già stata creata e che vi siano stati inseriti dati.

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>

Definizione del tipo di dati risultanti dall'uso di SELECT

Come impostazione predefinita, ciascuna riga restituita dall'istruzione SELECT viene creata come istanza Object con proprietà denominate appositamente per i nomi delle colonne del set di risultati e con il valore di ciascuna colonna come valore della proprietà associata. Tuttavia, prima di eseguire l'istruzione SQL SELECT, si può impostare su una classe la proprietà itemClass dell'istanza SQLStatement. Se si imposta la proprietà itemClass, ciascuna riga restituita dall'istruzione SELECT viene creata come istanza della classe designata. Il runtime assegna i valori delle colonne risultato ai valori delle proprietà facendo corrispondere i nomi delle colonne del set di risultati SELECT ai nomi delle proprietà della classe itemClass.

Tutte le classi assegnate come valore della proprietà itemClass devono avere un costruttore che non richiede alcun parametro. Inoltre, la classe deve presentare una sola proprietà per ciascuna colonna restituita dall'istruzione SELECT. Si considera errore se una colonna dell'elenco SELECT non possiede il nome di proprietà corrispondente nella classe itemClass.

Recupero parziale dei risultati SELECT

Come impostazione predefinita, l'esecuzione dell'istruzione SELECT recupera tutte le righe del set di risultati contemporaneamente. Una volta completata l'istruzione, di solito si elaborano in qualche modo i dati recuperati, ad esempio creando oggetti o visualizzando i dati su schermo. Se l'istruzione restituisce un gran numero di righe, l'elaborazione di tutti i dati allo stesso momento può occupare gran parte delle risorse del computer, il che a sua volta avrà come conseguenza il mancato aggiornamento dell'interfaccia utente.

È possibile migliorare le prestazioni apparenti dell'applicazione comandando al runtime di restituire un certo numero di righe di risultati alla volta. Così facendo, i dati dei risultati iniziali vengono restituiti più rapidamente. Inoltre, ciò consente di dividere in gruppi le righe dei risultati in modo che l'interfaccia utente venga aggiornata dopo l'elaborazione di ciascun gruppo di righe. Tenete presente che l'impiego di questa tecnica ha senso pratico solo nella modalità di esecuzione asincrona.

Per recuperare i risultati SELECT in parti, specificate un valore per il primo parametro del metodo SQLStatement.execute() (cioè il parametro prefetch). Il parametro prefetch indica il numero di righe da recuperare la prima volta che l'istruzione viene eseguita. Quando chiamate il metodo execute() di un'istanza SQLStatement, specificate un valore per il parametro prefetch. In tal modo può essere recuperato solo il numero specificato di righe.

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 

L'istruzione crea l'evento result che indica che è disponibile il primo gruppo di righe di risultati. La risultante proprietà data dell'istanza SQLResult contiene le righe di dati e la relativa proprietà complete indica se vi sono altre righe di risultati ancora da recuperare. Per recuperare altre righe di risultati, chiamate il metodo next() dell'istanza SQLStatement. Analogamente al metodo execute(), il primo parametro del metodo next() viene usato per indicare quante righe recuperare la prossima volta che viene creato l'evento 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); 
        } 
    } 
} 

L'istruzione SQLStatement crea un evento result tutte le volte che il metodo next() restituisce un gruppo successivo di righe di risultati. Di conseguenza, la stessa funzione listener può essere utilizzata per continuare ad elaborare i risultati (provenienti dalle chiamate next()) fino al recupero completo di tutte le righe.

Per ulteriori informazioni, vedete le descrizioni del metodo SQLStatement.execute() (la descrizione del parametro prefetch) e del metodo SQLStatement.next().