270 likes | 405 Views
ADO.NET 開發高手系列. 台灣微軟資深講師 從 1993 年開始於台灣微軟主講研討會 台灣微軟最有價值專家 兩度當選 MVP 資深電腦圖書作家 擁有 60 本以上的著作 資深技術顧問. 主講人:章立民. ADO.NET 開發高手線上教學課程 第六集 如何使用資料讀取器( SqlDataReader ). 什麼是資料讀取器. DataReader 物件。 順向 ( Forward-Only )且 唯讀 ( Read-Only )的資料流。 高效能的資料讀取方式。 較適合 單次 且 短時間 的資料擷取作業。
E N D
ADO.NET 開發高手系列 • 台灣微軟資深講師 • 從 1993 年開始於台灣微軟主講研討會 • 台灣微軟最有價值專家 • 兩度當選 MVP • 資深電腦圖書作家 • 擁有 60 本以上的著作 • 資深技術顧問 主講人:章立民
ADO.NET 開發高手線上教學課程第六集如何使用資料讀取器(SqlDataReader)
什麼是資料讀取器 • DataReader 物件。 • 順向(Forward-Only)且唯讀(Read-Only)的資料流。 • 高效能的資料讀取方式。 • 較適合單次且短時間的資料擷取作業。 • .NET Framework 中不存在一個名稱為 DataReader 的類別。 • 各種資料提供者會實作它們自己的資料讀取器類別: • SqlDataReader • OleDbDataReader • OdbcDataReader • OracleDataReader
如何建立資料讀取器 • 只能透過呼叫 Command 物件的 ExecuteReader方法來傳回,不能直接使用建構函式來個體化它: • SqlDataReader => SqlCommand.ExecuteReader • OleDbDataReader =>OleDbCommand. ExecuteReader • ExecuteReader 方法會將結果集內含於一個資料讀取器中傳回給您,因此您必須建立一個資料讀取器物件(也就是 SqlDataReader 物件)來擷取資料。 • 當您正在存取資料讀取器物件時,資料庫連接會保持開啟狀態,您必須在使用完畢後自行關閉資料庫連接。 • 不需要快取資料、結果集太大無法容納於用戶端電腦的記憶體中、亦或是要以順向且唯讀的方式來快取存取資料一次,則應該使用資料讀取器。
循序移至各筆資料列 • SqlDataReader.HasRows屬性 • 判斷 SqlDataReader 物件是否內含任何資料列。 • HasRows 屬性是 .NET Framework 1.1 所新增的屬性。 • SqlDataReader.Read方法 • 前移至下一筆資料列。 • SqlDataReader 的預設位置是在第一筆資料列之前。 • 判讀 Read 方法傳回的布林值。
如何取得所傳回資料列之特定欄位的內容 • 將欄位名稱傳遞給 SqlDataReader 物件:myReader("姓名") • 將欄位的序數(從0開始算起 )傳遞給 SqlDataReader 物件:myReader(0) • 使用 SqlDataReader 一系列的 Getxxx 方法(GetString…等)來取得欄位內容: • 一系列的 GetSqlxxx 方法(GetSqlString…等)專門用於取得 SQL Server 的欄位內容。 • 必須將欄位的序數傳遞給 GetSqlxxx方法。
取得多個結果集 • 呼叫 SqlDataReader.NextResult方法來將資料讀取器前移到下一個結果集。
程式範例 • DemoForm1.vb示範如何使用一個迴圈來反覆呼叫 SqlDataReader 物件的 Read 方法,並且將欄位名稱傳遞給 SqlDataReader 以便取得資料列之各欄位的內容。 • DemoForm2.vb示範如何使用一個迴圈來反覆呼叫 SqlDataReader 物件的 Read 方法,並且將欄位的序數傳遞給 SqlDataReader 以便取得資料列之各欄位的內容。 • DemoForm3.vb示範如何使用一系列的 GetSqlxxx方法去取得資料列之各欄位的內容。 • DemoForm4.vb示範如何使用欄位的序數但是兼顧到程式的易讀性。
DemoForm5.vb • GetName 方法用來取得欄位的名稱。 • GetDataTypeName 方法用來取得欄位的原始資料型別名稱。 • GetFieldType 方法用來取得代表物件之宣告型別的 Type 物件。 • FieldCount 屬性會傳回目前資料列中的欄位數目。
DemoForm6.vb • 示範如何建立一個介面,以便讓您您可以從特定的使用者資料庫中選取某一個使用者資料表,並將該資料表的所有資料列顯示於 ListView 控制項中。
DemoForm7.vb • 示範如何建立一個介面,以便當您從清單方塊(ListBox)中選取某一個客戶編號後,該客戶的所有訂貨明細資料便會顯示於 ListView 控制項中。
從資料庫取得結構描述資訊 • SqlDataReader.GetSchemaTable方法 • 所傳回的 DataTable 物件會內含 Transact-SQL 陳述式或預存程序所產生之結果集的結構描述資訊(亦即各欄位的中繼資料)。 • 所傳回的 DataTable 固定會擁有 23 個欄位,這些欄位分別用來存放特定的結構描述資訊。 • 所傳回之 DataTable 中的各筆資料列則分別代表結果集之每一個欄位的結構描述資訊。 • 如果您只是要取得 Transact-SQL 陳述式或預存程序所產生之結果集的結構描述資訊,而不需要提取資料列,您應該在呼叫 SqlCommand 物件的 ExecuteReader 方法時使用CommandBehavior.SchemaOnly作為其參數。 • 程式範例 DemoForm8.vb
讀取、寫入與顯示欄位中的 BLOB 值 • 討論對象:SQL Server 資料庫資料表的 image資料型別欄位。 • 二進位大型物件(Binary Large Object,簡稱 BLOB)。 • 本課程所介紹的寫法並不適用於 Access 與 SQL Server 之 Northwind 範例資料庫之 Employees 資料表的 Photo 欄位。 • 原因:儲存於 Photo 欄位中的點陣圖影像包含了 Visual Basic 6.0 OLE Container 控制項所建立的標頭資訊。
如何從 image 欄位提取 BLOB 值 • 資料讀取器的預設運作模式是一旦有一整列資料可以使用時,便立即將內送資料載入成資料列。BLOB 需要採用不同的處理方式。 • ExecuteReader(CommandBehavior.SequentialAccess) • 接收到資料時依序載入資料,而不必載入整列資料。 • 請注意傳回之欄位的順序。 • 務必依序存取資料讀取器所傳回的各個欄位。 • 使用資料讀取器的 GetBytes或 GetChars具型別存取子來存取 BLOB 欄位的資料,以便將資料填入陣列中。
GetChars 與 GetBytes 的語法 • GetChars( _ ByVal i As Integer, _ ByVal dataIndex As Long, _ ByVal buffer() As Char, _ ByVal bufferIndex As Integer, _ ByVal length As Integer) • GetBytes( _ ByVal i As Integer, _ ByVal dataIndex As Long, _ ByVal buffer() As Byte, _ ByVal bufferIndex As Integer, _ ByVal length As Integer)
程式範例 DemoForm9.vb • 從「虛擬工作室」資料表提取出所有資料列之「身份證字號」與「玉照」欄位的內容,然後將每一筆資料列之「玉照」欄位的影像資料分別寫出至 C:\Temp 中的一個 .jpg 圖檔中。 • 每一位人員之影像資料的 .jpg 圖檔將會以 “Employee-身份證字號.jpg” 的格式來命名。比方說,身份證字號為 A156401174 之人員的影像資料將會寫出成 Employee-A156401174.jpg 圖檔。 • 使用 GetBytes方法來傳回二進位資料。 • 欄位必須被依序存取,因此務必先存取目前資料列的「身份證字號」,然後再存取「玉照」。
如何將 BLOB 值寫入資料庫 • 構建出合適的 INSERT 或 UPDATE 陳述式(亦或是預存程序)。 • 將 BLOB 值指派給陳述式的參數或預存程序的輸入參數。 • 如果您的 BLOB 值被儲存成文字(例如:儲存在 text或 ntext資料型別的欄位中),則可以將 BOLB 值當作字串參數來傳遞。 • 如果您的 BLOB 值被儲存成二進位格式(例如:儲存在 image資料型別的欄位中),則可以將型別 byte 的陣列當作二進位參數來傳遞。
程式範例 • DemoForm10.vb示範如何替「虛擬工作室」資料表新增資料列時,將使用者所選取的 JPEG 影像檔(.jpg)寫入新資料列的「玉照」欄位中(「玉照」欄位是一個 image 資料型別的欄位)。 • DemoForm11.vb示範如何透過 UPDATE陳述式,以 Ch6 專案之 Images 資料夾中的 JPEG 影像檔(.jpg)來更新「虛擬工作室」資料表的「玉照」欄位內容。
如何將 image 欄位內的影像資料顯示在 PictureBox 控制項中 • 使用 SqlDataReader.GetBytes方法將 image 欄位內的資料讀入一個 Byte型別的陣列中。 • 將其置入一個 MemoryStream物件。 • 使用Image.FromStream方法將 MemoryStream 物件載入至 PictureBox 控制項的 Image屬性中。 程式範例:DemoForm12.vb
如何將 PictureBox 控制項中的影像資料寫回 image 欄位 • 您必須從 PictureBox 控制項提取影像資料並將其置入一個 MemoryStream 物件中。 • 將 MemoryStream 物件複製到一個 Byte 陣列中。 • 使用一個參數化的 SqlCommand 物件將 Byte 陣列寫入 image 欄位中。
程式範例 • DemoForm13.vb示範如何建立一個介面來讓使用者選取所需的 JPEG 影像檔並將其顯示於 PictureBox 控制項中,然後再將已顯示於 PictureBox 控制項中的影像寫回 image 資料型別的「玉照」欄位中。 • DemoForm14.vb示範如何建立一個包含 image 欄位之影像資料(亦即 BLOB 值)存取的新增、修改與刪除資料介面。
使用區塊讀取與寫入BLOB值 • 使用「區塊」(Chunk)來讀取與寫入 BOLB 值可以減少記憶體的耗用量,並提昇效率。 • Microsoft SQL Server:使用 READTEXT與 UPDATETEXT陳述式。 • ADO.NET 資料提供者並未擁有 DAO 與 ADO Recordset 物件的 GetChunk 與 AppendChunk 方法。
程式範例 DemoForm15.vb • 示範如何叫用 SqlChunkBLOB2File 與 ChunkFile2SqlBLOB 這兩個使用者自訂函式。SqlChunkBLOB2File 函式會使用區塊來讀取 BLOB 值,ChunkFile2SqlBLOB 函式會使用區塊寫入 BLOB 值。 • 處理對象:Northwind 資料庫之 Categories 資料表的 Picture 欄位。
結束 • 別忘了定期上下列網站: • MSDN 中文網站http://www.microsoft.com/taiwan/msdn/ • 微軟技術社群網站http://www.microsoft.com/taiwan/community • 微軟最有價值專家 MVPMicrosoft Most Valuable Professionals • 微軟爲什麼要選拔 MVP • 誰可以申請為微軟最有價值專家(MVP) • 下集主題:如何建立與使用 DataTable • 再會