データベースからのデータの取得

Adobe AIR 1.0 およびそれ以降

データベースからデータを取得する操作には 2 つのステップが含まれます。まず、データベースから取得するデータのセットを記述する 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 ステートメントの実行が完了したら、次の手順として、取得したデータにアクセスします。 SELECT ステートメントの実行結果のデータを取得するには、SQLStatement オブジェクトの getResult() メソッドを呼び出します。

var result:SQLResult = selectStatement.getResult();

getResult() メソッドは SQLResult オブジェクトを返します。SQLResult オブジェクトの data プロパティは 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 の結果セットの各データ行は、 data 配列に格納される Object インスタンスになります。そのオブジェクトには、結果セットの列と同じ名前のプロパティがあります。そのプロパティに、結果セットの列の値が格納されます。例えば、「itemId」、「itemName」および「price」の 3 つの列を含む結果セットを SELECT ステートメントで指定した場合は、 itemId itemName および price の 3 つのプロパティを持つ Object インスタンスが結果セットの各行について作成されて、各プロパティにそれぞれの列の値が格納されます。

次のコードリストでは、text プロパティが SELECT ステートメントの SQLStatement インスタンスを定義しています。このステートメントは、 employees というテーブルのすべての行の firstName 列と lastName 列の値を含む行を取得します。この例では非同期実行モードを使用しています。実行が完了したら、 selectResult() メソッドを呼び出します。その後、 SQLStatement.getResult() を使用して結果行にアクセスして、 trace() メソッドを使用して表示します。このリストでは、 conn という名前の SQLConnection インスタンスが既に作成されてデータベースに接続されていることと、「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>

次のコードリストで使用されているのは、先ほどの例と同じテクニックです。ただし、今度は同期実行モードを使用しています。この例では、text プロパティが SELECT ステートメントの SQLStatement インスタンスを定義しています。このステートメントは、 employees というテーブルのすべての行の firstName 列と lastName 列の値を含む行を取得します。 SQLStatement.getResult() を使用して結果行にアクセスして、 trace() メソッドを使用して表示します。このリストでは、 conn という名前の SQLConnection インスタンスが既に作成されてデータベースに接続されていることと、「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 インスタンスとして作成されます。この Object インスタンスには結果セットの列名と同じ名前のプロパティがあり、各列の値がプロパティの値として格納されます。しかし、SQL SELECT ステートメントを実行する前に SQLStatement インスタンスの itemClass プロパティを設定してクラスを指定することもできます。 http://help.adobe.com/ja_JP/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() メソッドを呼び出します。 next() メソッドの最初のパラメーターは、 execute() メソッドと同様に、次に 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); 
        } 
    } 
} 

result イベントは、 next() メソッドによって結果行の続きのセットが返されるたびに送出されます。したがって、すべての行が取得されるまで同じリスナー関数を使用して( next() の呼び出しの)結果の処理を続けることができます。

詳しくは、 SQLStatement.execute() メソッド(の prefetch パラメーター)の説明と SQLStatement.next() メソッドの説明を参照してください。