從資料庫擷取資料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() 方法的說明。 |
|