E N D
第十七章 ADO .NET資料庫連線與存取
17.1 如何引用ADO .NET命名空間 • 由上一章我們知道,在 .NET Framework的架構中是由所使用資料庫(來源)來決定使用SQL .NET Data Provider或是OLE DB .NET Data Provider。由於這兩者 .NET Data Provider分屬不同的命名空間(Namespace),因此,必須使用Imports敘述來引用對應ADO .NET的命名空間,這樣才能在撰寫程式時,能使用較簡潔的ADO .NET物件來存取資料庫。至於ADO .NET包括那些命名空間可以如下圖,透過功能表的【檢視(V)/物件瀏覽器(J)】來查詢
下面只列出上圖中ADO .NET常用的相關命名空間說明: • 1. System.Data • 是ADO .NET命名空間的核心,大部分是由構成ADO .NET架構的類別所組合而成的。這些類別是Managed應用程式用來存取資料的主要方法。它定義了Tables、Rows、Columns、Constraints和 DataSet所代表的型別。由此可知DataSet類別是位於System.Data命名空間中,因此在撰寫程式時若有使用到DataSet類別,必須在程式的最開頭使用Imports敘述來引用此命名空間,其寫法如下:
2. System.Data.OleDb • 這個命名空間定義了允許您連接到OLE DB這類型的資料來源、接受 SQL查詢和透過Fill 方法將資料填入DataSet中。這些資料來源包括Access、Excel、SQL Server 7.0以上版本的資料庫…等。若在程式中使用這類型的資料庫,必須在程式的最開頭使用Imports敘述引用此命名空間,其寫法如下: • 在OLE DB .NET Data Provider下,所使用的ADO .NET物件名稱的前面必須加上OleDb,如:OleDbConnection、OleDbCommand、OleDbDataReader…等。
3. System.Data.SqlClient • 這個命名空間允許您連接到SQL Server 7.0(含)以上版本的資料庫,使用這類型可以直接和SQL Server連接。若在程式中使用這類型的資料庫,必須在程式的最開頭使用Imports敘述含入此命名空間,其寫法如下: • 在SQL .NET Data Provider下,所使用的ADO .NET物件名稱的前面必須加上Sql,如:SqlConnection、SqlCommand、SqlDataReader…等。
下表即是ADO .NET在各所屬命名空間中各物件命名對照表:
17.2 使用Connection物件開啟、關閉資料庫的連接 • ADO .NET所提供的Connection物件,主要是用來與資料庫來源之間建立連接。Connection物件提供下列兩種常用方法: 1.Open方法:用來開啟與資料庫的連接。 2.Close方法:用來關閉與資料庫的連接。 • 接著介紹ADO .NET架構下,如何引用ADO .NET命名空間、開啟與關閉所提供兩種不同資料來源連接的程式片段:
Case 1 引用System.Data.OleDb命名空間(適用Access、Excel…等資料庫) • 引用命名空間:Imports System.DataImports System.Data.OleDb • 宣告OleDbConnection連接物件:Dim myConnection As OleDbConnection • 宣告一個名稱為connStr的字串變數,用來存放資料庫的連線字串,並指定資料庫所在的真實路徑:Dim connStr As String = _ "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & 資料庫真實路徑
建立OleDbConnection物件並指定其資料庫的連接字串:myConnection = New OleDbConnection( connStr ) • 使用Open方法開啟與資料庫的連接:myConnection.Open() • 完成資料庫存取後再使用Close方法關閉與資料庫的連接:myConnection.Close() • 以上完整程式寫法如下:
Case 2 引用System.Data.SqlClient命名空間(適用SQL Server 7.0以上版本的資料庫) • 操作方式和 Case 1 類似,先宣告SqlConnection物件,再建立SqlConnection物件並指定其連接的資料庫,最後使用Open方法開啟與資料庫的連接、使用Close方法關閉與資料庫連接。但SqlConnection及OleDbConnection物件的資料庫連線字串寫法不一樣。
以下是SqlConnection物件連接字串的參數設定: • server:可指定資料庫的伺服器名稱、IP位址、localhost(代表本機)。 • database:SQL Server資料庫的名稱。 • uid:資料庫連接帳號,sa使用SQL表示資料庫管理者帳號。 • pwd:資料庫連接密碼。 • 若uid與pwd都不加,則表示使用目前登入系統的Windows帳號來連接SQL Server,如果在ASP .NET網頁(Web Form)中,則是使用「ASP.NET」這個帳號。另外各項參數名稱大小寫不分。
17.3 使用DataReader物件讀取資料表記錄 • 上一節已經介紹過如何開啟與關閉資料庫的連接,本節將陸續介紹對已開啟的連接資料庫,如何透過ADO .NET架構內的Command及DataReader物件來讀取資料庫內的資料。 • 17.3.1 Command物件 • Command物件可以讓您執行SQL資料庫命令,以傳送和修改資料、執行預存程序(Stotred Procedure)、並且傳送或擷取參數資訊。所以,Command物件透過SQL命令可從資料來源擷取資料,也可將異動過的資料傳回資料來源。此物件提供下列兩種方法來存取資料庫的內容:
1.ExecuteReader方法執行Command物件中所指定SQL 語法的Select命令,建立一個DataReader物件以進行資料的瀏覽。 2.ExecuteNonQuery方法使用Command物件的ExecuteNonQuery方法,可以新增、刪除、修改資料庫中的資料,也就是說執行SQL語法中的Insert、Delete、Update命令。
17.3.2 DataReader物件 • 使用DataReader物件可以由資料庫中順向(Forward-only)逐筆讀取資料流中的資料列,由於並不是一次將所有資料傳向用戶端的記憶體中,因此能提升應用程式的效能和降低系統的負荷量,使得執行速度快且不佔用記憶體太多的資源。DataReader物件讀取資料方式是先透過Connection物件和資料庫連接,再經由Command物件的ExecuteReader方法執行SQL Select查詢命令擷取出欲查詢的資料,再透過DataReader物件中所提供的屬性和方法,將擷取的資料以唯讀方式由記錄指標所指的資料列順向逐筆處理,將資料放入記憶體或直接顯示在表單上。但要注意在DataReader開啟時間,必須和資料庫一直保持連接,此時Connection只能供DataReader使用,必須等到DataReader關閉後,才能允許執行Connection的任何命令。下圖即是DataReader物件讀取資料庫記錄的流程。
至於在程式中如何建立DataReader物件,其寫法如下: • Case 1 引用System.Data.OleDb命名空間(適用Access、Excel…等資料庫) • 宣告myDataReader、myCommand分別屬於OleDbDataReader、OleDbCommand物件。寫法如下:Dim myCommand As OleDbCommand Dim myDataReader As OleDbDataReader • 建立myCommand屬於OleDbCommand物件,並設定所要執行的SQL命令。寫法如下:(關於SQL命令請參閱17.5節)myCommand = New OleDbCommand (“SQL命令”, myConnection) • 使用OleDbCommand物件的ExecuteReader方法,執行所指定的SQL查詢命令建立myDataReader物件,只要透過myDataReader物件所提供的方法及屬性即可進行資料的瀏覽。寫法如下:myDataReader = myCommand.ExecuteReader()
Case 2 引用System.Data.SqlClient命名空間(適用SQL Server 7.0以上版本的資料庫)
17.3.3 DataReader常用的屬性與方法 • 透過Command物件的ExecuteReader方法執行SQL的查詢命令即可建立DataReader物件,DataReader物件內所存放的是查詢結果的資料串流,你可使用下表DataReader物件所提供的屬性與方法來逐一取得每筆記錄或相關欄位的資料:
17.3.4 如何使用DataReader讀取查詢結果 • 當你想透過DataReader物件來讀取由資料庫中所擷取出的查詢結果,可以使用重複結構來檢查記錄指標是否已經指到EOF檔案結尾符號,若記錄指標尚未指到EOF表示資料未讀完,便可利用上表DataReader所提供的方法和屬性,順向逐一取得每個欄位的名稱和該欄位內所存放的資料;若記錄指標指到EOF表示資料已經讀取完畢,便可結束讀取動作。
1. 如何透過DataReader物件取得資料列(記錄)的欄位名稱 • 利用FieldCount屬性取得欄位總數,再將此傳回值減1取得欄位註標的最大值,再利用For…Next配合GetName方法分別取得各欄位的名稱,並將欄位名稱顯示在表單的TextBox1文字方塊控制項上面。
2. 如何透過DataReader物件來顯示各資料列欄位內的資料。 • 有下列兩種方式,第一種方式的使用時機是當需要顯示所有欄位時使用,第二種方式是當僅顯示部分欄位內容時使用: • 透過Do While…Loop敘述判斷記錄指標是否指到EOF檔案結尾符號?若記錄指標尚未指到EOF,表示資料列尚未讀完,此時透過For…Next敘述配合Item屬性,將記錄指標所指到的資料列(記錄)各欄位內容,顯示在表單的TextBox1控制項上面。
利用Do While…Loop及Read方法判斷記錄指標是否指到EOF(檔案結尾符號),若沒有指到EOF,則將目前指標所指向的記錄從資料庫讀出來並放到DataReader物件中,再使用Item屬性讀取某一欄位的資料,並顯示在TextBox1控制項物件內。
【執行結果】 • 將書附光碟ch17資料夾下的DataReader1子資料夾複製到你的電腦,再將DataReader資料夾內所有檔案的唯讀屬性取消,然後執行 [DataReader1\bin\Debug\DataReader1.exe] 執行檔,結果出現下圖表單:
Step1.進入VB 2005的整合開發環境,新增一個Windows應用程式專案。其專案命名為「DataReader1」,記得將專案進行存檔。 • Step2.請將書附光碟ch17資料夾下的ScoreDb.mdb 資料庫複製到目前製作專案的 [DataReader1\bin\Debug] 資料夾下,然後再將ScoreDb.mdb的唯讀屬性取消。 • Step3.建立如下所示之表單:
Step4.引用ADO .NET的命名空間 • 執行功能表的【檢視(V)/程式碼(C)】開啟「檢視程式碼」視窗,然後在程式的最開頭必須引用(Imports)對應的ADO .NET命名空間。因為我們使用Access資料庫,所以請在程式的最開頭引用(Imports)System.Data.OleDb,在下面虛框處即是指定要撰寫的程式碼:
【說明】 1.「DataReader1」範例是引用System.Data.OleDb命名空間,所以此範例中的ADO .NET物件名稱之前都必須加上OleDb。 2.第6行:設定資料庫的連接字串及資料庫所在之真實路徑。 3.第7行:將可查詢SCORE資料表所有記錄的SQL字串指定給selectcmd字串變數。 4.第8行:宣告OleDbConnection類別的conn物件,宣告OleDbDataReader類別的reader物件,宣告OleDbCommand類別的cmd物件。 5.第9行:建立conn物件並指定connStr連接字串。 6.第10行:使用conn物件的Open方法來開啟連接的資料庫。
7.第11行:建立cmd物件,並設定所要執行的SQL語法及conn物件。7.第11行:建立cmd物件,並設定所要執行的SQL語法及conn物件。 8.第12行:使用cmd物件的ExecuteReader方法執行SQL語法建立查詢結果的reader物件。 9.第13-15行:使用For…Next逐一取得SCORE資料表的欄位名稱並放入txtShow控制項物件內。 10.第17-22行:使用巢狀重覆結構配合reader物件的FieldCount及Item屬性逐一取得SCORE資料表的欄位資料,並放入txtShow控制項物件內。 11.第23行:使用conn物件的Close方法關閉資料庫的連線。 12.Item屬性也可以指定欄位名稱,範例「ch17\DataReader2」就是使用此種寫法:
本例可將Item改用GetValue,但要注意GetVaue後面接的參數不能指定欄位名稱。例如範例「ch17\DataRedaer3」就是使用這種寫法:
17.4 使用DataSet物件讀取資料表記錄 • 17.4.1 DataSet物件 • DataSet物件可說是ADO .NET的主角,它像是一個記憶體中的資料庫,它採用離線存取資料庫的方式。例如:資料庫應用程式與SQL Server資料庫分別安裝在不同的主機上,當資料庫應用程式向SQL Server資料庫要求取得資料時,SQL Server資料庫會將所要擷取的全部資料傳送到執行資料庫應用程式所在電腦的記憶體(DataSet)中,此時可與資料庫中斷連線。當DataSet中的資料更新完畢後,再重新和SQL Server資料庫進行連線,將資料全部一次更新到SQL Server資料庫中。因此DataSet執行效率佳,適用於多用戶端資料存取,但此種方式須耗費較多的記憶體空間。在DataSet中可以包含一個以上的DataTable物件,DataTable物件相當於主記憶體中的一個資料表。
17.4.2 DataAdapter物件 • DataAdapter物件是資料庫和DataSet之間溝通的橋樑。DataAdapter物件使用Command物件執行SQL命令,將由資料庫所擷取的資料送到DataSet,此時便可使用DataTable物件來存取資料表,將DataSet裡面的資料經過處理後再送回資料庫。下圖即是DataAdapter物件架構:
17.4.3 如何使用DataAdapter物件 • 使用下列步驟可產生名稱為「成績單」與「股票行情表」的DataTable物件。 • Step1.建立名稱為myDataSet 的DataSet物件以及宣告myAdapter是一個DataAdapter物件。 • Step2.建立myAdapter物件並指定所要執行的SQL命令及指定欲連接的資料庫
Step3.使用DataAdapter物件的Fill方法,將查詢資料的結果放到DataSet物件中。此時DataSet物件中即會產生一個DataTable物件,該DataTable物件會以資料表的方式存放查詢資料的結果,所以只要透過DataTable物件即可取得SQL命令所查詢的資料。Step3.使用DataAdapter物件的Fill方法,將查詢資料的結果放到DataSet物件中。此時DataSet物件中即會產生一個DataTable物件,該DataTable物件會以資料表的方式存放查詢資料的結果,所以只要透過DataTable物件即可取得SQL命令所查詢的資料。
上述程式在DataSet物件中產生了「成績單」及「股票行情表」的DataTable物件。你也可以透過DataSet物件所提供的Tables集合物件(由DataTable物件所構成),來指定要取用那一個DataTable物件。 • 上述程式也可改用表格編號來取得DataTable物件,Tables集合物件的註標起始值為0。
透過下面程式來取得DataTable的總數或DataTable名稱。透過下面程式來取得DataTable的總數或DataTable名稱。 • 若DataTable物件指定給DataGridView控制項的DataSource屬性,則目前表單上DataGridView控制項內會顯示該DataTable物件中的所有資料,如下程式:
【執行結果】 • 將書附光碟ch17資料夾下的DataSet1子資料夾複製到你的電腦,再將DataSet1子資料夾內所有檔案的唯讀屬性取消。 • 執行 [DataSet1\bin\Debug\DataSet1.exe] 執行檔開啟本例表單,如下圖成績單、股票行情表、碁峰圖書這三個DataTable物件名稱都加到ComboBox控制項中,DataGridView控制項預設顯示碁峰圖書DataTable物件之內容。選取ComboBox控制項之DataTable物件名稱,然後再按 鈕,此時DataGridView控制項即會顯示所選取的DataTalbe物件之所有資料。
Step1.進入VB 2005的整合開發環境,新增一個Windows應用程式專案。其專案命名為「DataSet1」,記得將專案進行存檔。接著再將書附光碟ch17資料夾下的DB.mdb複製到目前製作DataSet1專案的bin\Debug資料夾下,然後再將DB.mdb唯讀屬性取消。 • Step2.建立如下所示之表單: