Transcript CH08

CH08
資料庫
程式設計
ADO.NET資料庫程式設計
資料庫觀念
在上一章介紹過檔案系統之後,這一章要介紹的是另一個更重要
的機制--『資料庫系統』。
資料庫也是一個檔案,但是和檔案系統有所不同的是,資料庫提
供了結構化的資料儲存和檢索方式,讓查詢和存取更有效率。
檔案系統可以幫助我們將檔案儲存在硬碟(或是其他的媒介)當中,
待需要的時候再載入電腦的記憶體當中。但是儲存於硬碟上的檔案是
透過目錄與檔名的方式來存放,檔案的內容則是各種文字或是Binary
Code,與現實生活當中的資料結構差異太大,往往並不容易分類搜尋
或是檢索。
而資料庫就是在這個狀況下誕生的機制,它可以幫助使用者(或
是程式設計師)以更具有結構的方式來儲存資料。
ADO.NET資料庫程式設計
資料庫觀念
如果這些資料都透過檔案系統來儲存,當我們要利用
電腦進行分類(例如找到所有1999年訂購『白起司』的
客戶)恐怕是相當困難。因此就有了Access、SQL
Server、Oracle等『資料庫系統』來幫助我們,對這些
複雜的資料進行處理。
這個畫面是某公司的訂單輸入畫面,您會發現它包含了相當多不同類型的資料,
例如客戶的資料(包含送貨地址…)、公司內的業務人員、要訂購的產品、數量與
金額…等。
ADO.NET資料庫程式設計
資料庫觀念
我們可以將複雜的單據,化作單純的表格形式(我們稱之為資料表),將同一類的
資料儲存在一起方便管理。
例如,底下是幾個不同的資料表(分別是客戶資料、產品資料、以及訂單資料):
ADO.NET資料庫程式設計
資料庫觀念
一個資料表當中,會有許多的記錄:
每一筆這樣的記
錄我們稱為資料
錄(Data Row)
因此,一筆資料錄當中,有多個欄位,每個欄位就可
以儲存不同的資料,有點類似Excel的sheet,讓使用
者可以輕鬆的將資料儲存到資料庫中。資料存入資料
庫之後,我們就可以針對特定的欄位排序或是以特定
的條件搜尋。
例如,我們可以透過簡單的指令碼找出上圖這個
『訂貨主檔』資料表當中,客戶名稱為『東遠銀行』
的所有訂單資料,並且可以依照訂購的日期先後順
資料錄具有多的欄位,我們稱之為
序來排序顯示出來。
資料欄(Data Column)
ADO.NET資料庫程式設計
資料庫觀念
資料庫不僅可以支援單一條件單一資料表的搜尋,
還可以讓資料表之間交叉比對,例如:找出『公司
地址在台北市』且『今年訂單總運費超過5000元』
我們還可以將兩三個不同的資料表加以關聯,利用多重條件找出符合的資料:
的客戶名單。(這些客戶可能我們要換一家更便宜的
市區快遞公司來送貨)
ADO.NET資料庫程式設計
資料庫對VB.NET開發人員的意義
我們可以透過資料庫現有的這些功能,幫助我們設計的資訊系統來存取資料。資料庫
本身均包含搜尋、排序、以及管理功能,絕大部分的資料庫也支援標準的SQL語言,
讓開發人員或是使用者可以透過簡單的SQL語法來操作資料庫中的資料,對資料進行
搜尋、新增、修改、刪除等功能。
因此,Visual Basic 2005的開發人員,在撰寫資料庫應用程式前,可以在資
料庫中先建立資料表,待資料表建立完成之後,再透過程式來新增或是編
輯資料。在程式運作的過程當中,資料的儲存和搜尋,都是透過資料庫來
完成的,而Visual Basic 2005所開發的程式,則負責提供使用者操作介面,
讓程式的使用者可以在畫面上輸入資料,進行資料的驗證,最後透過程式
碼將資料儲存到資料庫中。
ADO.NET資料庫程式設計
資料庫對VB.NET開發人員的意義
畫面上的使用者介面您應該相當熟悉,多半是TextBox與Label,再加上一個ToolStrip(工具列)
就完成了。但是程式的核心絕對不只是畫面上的操作方式,例如搜尋、上下筆的切換、或是
修改儲存等等,重點是如何把使用者輸入的資料儲存到資料庫中,以及如何讀取出來。
ADO.NET資料庫程式設計
資料庫對VB.NET開發人員的意義
當我們利用VS2005建立出上頁的輸入畫面,並且透過程式碼讓使用者輸入的資料存入資料庫
之後,您可以檢視資料庫中的內容,將會呈現出下面這樣的樣式:
ADO.NET資料庫程式設計
基本SQL語法
我們前面提到過,絕大部分的資料庫都支援SQL語法,可支援資料庫的新增、修改、刪除與搜
尋功能。同樣的,我們剛才建立的SQL Server 2005 Express資料庫也是,我們先看資料的搜尋
部份。
Select語法
Select語法:
Select 欄位1, 欄位2, 欄位3… From 資料表名稱
資料的搜尋可以使用Select語法,這個命令會傳回資料表當中符合條件的記錄,符合
條件的記錄可能不只有一筆,而是多筆資料,我們稱這些搜尋出來的結果(一筆或多
筆資料)為檢視表(view)。
範例:
select 客戶編號, 公司名稱, 連絡人 from 客戶
ADO.NET資料庫程式設計
Select語法
select 客戶編號, 公司名稱, 連絡人 from 客戶
得到的資料如下圖,作者撰寫了一個『SQL語法測試
程式(CH08-01)』,您可以在TextBox當中輸入Select
語法,按下『執行』鈕之後,即可將資料顯示在下方
的DataGridView中:
上面的Select命令,所搜尋出符合條件的資
料會回傳到VB程式碼中,成為一個View,
填入DataGridView控制項中。
ADO.NET資料庫程式設計
Select語法
Select語法也支援排序功能,您只須要在Select語法的後面加上Order By [欄位名稱],即可針對
搜尋到的資料排序:
select * from 客戶 order by 公司名稱
其中的『*』代表所有的欄位(在您需要取得資
料表中所有欄位時,可以省去輸入欄位名稱),
執行的結果如上圖。
ADO.NET資料庫程式設計
Select語法
Order By後面若有多個欄位,可以『,』分隔,您可以在欄位後面接上Asc或Desc,指定該欄位
的排序方式是由小到大(Asc)還是由大到小(Desc),當您省略時,以Asc為預設值。
select 城市, 公司名稱, 地址, 連絡人 from 客戶 order by 城市 Desc, 公司名稱 Asc
您也可以同時以多個欄位來排序,例如上面這樣
的SQL語法,可以取得先以『城市』欄位由大到
小排序,當『城市』欄位相同時,再以『公司名
稱』由小到大排序的資料
ADO.NET資料庫程式設計
Select語法
除了Order By之外,Select最重要的功能是資料的過濾篩選,您可以透過Where關鍵字來決定讀
取資料時哪些要顯示出來。
select * from 客戶 where 城市='台北市'
ADO.NET資料庫程式設計
Select語法
除了『欄位名稱=’值’』之外,您還可以透過Like關鍵字,搜尋局部相同的資料,例如:
select * from 客戶 where 城市='台北市' and 連絡人 like '陳%'
由於前面提過Like的意思是,字串中只需要部分相同,而不需全部
相同,即被視為符合,因此『連絡人 like '陳%'』這個條件,代表連
絡人名稱開頭的一個字只要是『陳』,都會被篩選出來。而『%』
符號的意思是,代表不確定數量的任何文字,因此只要連絡人欄位
的開頭是『陳』的資料,都符合過濾的條件。
ADO.NET資料庫程式設計
Insert語法
除了搜尋之外,另一個很重要的功能,就是資料的新增,資料新增語法結構如下:
Insert into 資料表名稱 (欄位名稱1, 欄位名稱2, 欄位名稱3, …)
values (第一個欄位的值, 第二個欄位的值, 第三個欄位的值, …)
例如:
Insert into 客戶 (客戶編號, 公司名稱, 連絡人, 連絡人職稱)
values ('Atest','測試公司','David先生','總經理')
請注意,在SQL語法當中,所有的字串是以單引號『’』所包圍的文字。例如:
Insert into 客戶 (客戶編號, 公司名稱, 連絡人, 連絡人職稱)
values ('Atest','測試公司','David先生','總經理')
這些以單引號『’』所包圍的
文字,都是字串。
ADO.NET資料庫程式設計
Delete語法
Delete語法的功能為刪除記錄,您可以刪除特定一筆資料,或是刪除任何符合條件的資料,其
語法如下:
Delete from 資料表名稱 [Where 過濾條件]
同樣的Where後面也可比照Select命令一樣,透過And, Or, 或是Like等關鍵字,組出適當的刪除
條件,凡是符合條件的資料都會被刪除,例如:
Delete from客戶 Where 城市 = ‘台北市’
上面這樣的指令,會刪除所有在城市欄位中資料為『台北市』的客戶資料。請注意,如果您
直接輸入:
Delete from客戶
而忽略where子句,資料庫將會不問條件,一律將『客戶』資料表中所有的資料刪除。
ADO.NET資料庫程式設計
Update語法
Update語法則可用來更新資料庫中的資料,其語法如下:
Update 資料表名稱 Set 欄位 = 值, 欄位 = 值, …
[Where 過濾條件]
和Delete敘述一樣,如果您忽略Where子句,系統會不問條件的一律將該資料表中所有的記錄
都加以修改(修改的欄位與內容值依照Set子句決定)。
在程式中我們有兩種更新資料的場合,
其中一種是『修正資料』,
另一種是『計算出某種結果』。
ADO.NET資料庫程式設計
Update語法
存放數字
的欄位’
此為Boolean欄位,只有Yes或No兩
種可能(分別以1或0)來表示
Update 產品資料 Set 不再銷售 = 1
將會把『所有的產品』設為不再銷售。
(但一般我們不常這麼做,除非公司準備結束營業…)
ADO.NET資料庫程式設計
Update語法
存放數字
的欄位’
此為Boolean欄位,只有Yes或No兩
種可能(分別以1或0)來表示
Update 產品資料 Set 不再銷售 = 1 where 庫存量 < 5
上面這段指令,將會把所有庫存量小於5的資料設為不再銷
售。這類的更新處理我們稱之為『資料修正』。
ADO.NET資料庫程式設計
Update語法
存放數字
的欄位’
此為Boolean欄位,只有Yes或No兩
種可能(分別以1或0)來表示
update 產品資料 Set 單價 = 單價*1.1 where 單價<10
上面這段指令將所有單價小於10的產品,通通調漲價格,增
加一成的售價。這種更新即是為了計算出某種結果。
ADO.NET資料庫程式設計
如何透過VB程式碼存取資料庫
執行左方SQL
Command
DataGridView
執行左方的Select SQL
Command並將回傳值(Data
View)填入下方的
DataGridView當中。
CH08-03專案
ADO.NET資料庫程式設計
透過DbAccess類別存取資料庫
EX:CH08-03\Form1.vb
0000: ‘透過物件執行SQL讀取資料(按下重新顯示鈕)
0001: Private Sub Button1_Click(ByVal sender As System.Object,
在這裡指定要存取的SQL
ByVal e As System.EventArgs) Handles Button1.Click
Server 2005 Express資料庫。
0002:
'建立資料庫物件
0003:
Dim db As New DbAccess("cNorthWind.MDF")
0004:
'定義DataTable(用來接收回傳結果)
0005:
Dim dt As New Data.DataTable
0006:
'透過GetDataTable執行SQL命令,並且取得回傳結果放入dt中
0007:
dt = db.GetDataTable(Me.txb_select.Text)
0008:
'將DataGridView的資料設為dt
執行TextBox中的Select命令,傳
0009:
Me.DataGridView1.DataSource =回的資料會填入DataTable中
dt
0010: End Sub
ADO.NET資料庫程式設計
透過DbAccess類別將資料寫回資料庫
EX:CH08-03\Form1.vb
0000: '執行SQL異動命令
0001: Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
0002:
'建立資料庫物件
0003:
Dim db As New DbAccess("cNorthWind.MDF")
0004:
Dim ret As Integer
這邊填入要執行的SQL指令
0005:
'透過ExecuteCmd方法,來執行SQL命令,並且將回傳值(受影響的資料
錄筆數)放置到ret變數中
0006:
ret = db.ExecuteCmd(Me.txb_cmd.Text)
0007:
'如果沒有任何資料受影響,可能發生失敗
0008:
If ret <= 0 Then
0009:
MsgBox("沒有資料受影響,可能失敗!", MsgBoxStyle.Exclamation)
0010:
Else
0011:
MsgBox("完成!", MsgBoxStyle.Information)
0012:
End If
0013: End Sub
ADO.NET資料庫程式設計
透過DbAccess類別和ADO.NET來處理資料
我們撰寫了DbAccess類別來幫我們完成資料庫存取的功能,您可以透過
這個DbAccess類別完成絕大部分的資料庫存取需求,而存取資料庫的核
心程式碼其實位於DbAccess類別當中。
我們會在後面再介紹DbAccess類別中的程式碼。
前面我們已經明白如何透過DbAccess類別將資料庫中的資料讀取出來,
而回傳的資料結構就是DataTable,接著我們要來看,如何透過DataTable
來處理資料,例如將資料顯示到畫面上供使用者編輯或瀏覽。
在.NET Framework當中,對資料庫的處理是透過ADO.NET架構,
ADO.NET是一組專門負責資料庫存取與運作的類別,它可以讓開發人員
以一致的方式存取資料來源。不用因為需要存取不同的資料來源(資料
庫),就針對不同的資料來源撰寫個別的程式碼。
而前面我們介紹過的DataTable,就是ADO.NET所提供的一個類別。
ADO.NET資料庫程式設計
DataTable與DataRow類別
ADO.NET資料庫程式設計
將畫面上的資料寫回資料庫
cNorthWind.MDF
ShowData(ByVal id As Integer)
將第N筆資料顯示在畫面上
ADO.NET資料庫程式設計
EX:CH08-02\Form1.vb
'顯示資料
Sub ShowData(ByVal id As Integer)
'連結資料庫
Dim db As New DbAccess("cNorthWind.MDF")
'抓取編號為id的資料
Dim dt As DataTable = db.GetDataTable("select * from 員工 where 員工編號=" & id)
'如果沒有該筆資料
If dt.Rows.Count <= 0 Then
MsgBox("沒有編號為" & id & "的資料!")
Exit Sub
End If
'如果找到資料,則顯示出來
Me.txb_內部分機號碼.Text = dt.Rows(0).Item("內部分機號碼")
Me.txb_名.Text = dt.Rows(0).Item("名")
Me.txb_地址.Text = dt.Rows(0).Item("地址")
Me.txb_姓名.Text = dt.Rows(0).Item("姓名")
Me.txb_員工編號.Text = dt.Rows(0).Item("員工編號")
Me.txb_附註.Text = dt.Rows(0).Item("附註")
Me.txb_電話號碼.Text = dt.Rows(0).Item("電話號碼")
Me.txb_稱呼.Text = dt.Rows(0).Item("稱呼")
Me.txb_職稱.Text = dt.Rows(0).Item("職稱")
Me.dtp_雇用日期.Text = dt.Rows(0).Item("雇用日期")
Me.dtp_出生日期.Text = dt.Rows(0).Item("出生日期")
End Sub
ADO.NET資料庫程式設計
將資料庫中讀取到的資料填入畫面
cNorthWind.MDF
ToolStrip_btn_Save.Click
ADO.NET資料庫程式設計
EX:CH08-02\Form1.vb
0000: Private Sub ToolStrip_btn_Save_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles ToolStrip_btn_Save.Click
0001:
Dim db As New DbAccess("cNorthWind.MDF")
0002:
Dim sql As String = ""
0003:
'建立 Update 敘述(請注意當中使用到了參數)
0004:
sql += "update 員工 set "
0005:
sql += " 內部分機號碼=@內部分機號碼, "
0006:
sql += " 名=@名, "
0007:
sql += " 地址=@地址, "
0008:
sql += " 姓名=@姓名, "
0009:
sql += " 附註=@附註, "
0010:
sql += " 電話號碼=@電話號碼, "
0011:
sql += " 稱呼=@稱呼, "
0012:
sql += " 職稱=@職稱, "
0013:
sql += " 雇用日期=@雇用日期, "
0014:
sql += " 出生日期=@出生日期 "
0015:
'sql += " 相片=@相片 "
0016:
sql += " where 員工編號 = " & Me.txb_員工編號.Text
(…未完…)
ADO.NET資料庫程式設計
EX:CH08-02\Form1.vb
(…續…)
0017:
'我們建立了一個SQL Command物件
0018:
Dim dc As New SqlClient.SqlCommand(sql)
0019:
'並且填入 Parameters(要對應前面Update敘述的參數)
0020:
dc.Parameters.Clear()
0021:
dc.Parameters.AddWithValue("內部分機號碼", Me.txb_內部分機號碼.Text)
0022:
dc.Parameters.AddWithValue("名", Me.txb_名.Text)
0023:
dc.Parameters.AddWithValue("地址", Me.txb_地址.Text)
0024:
dc.Parameters.AddWithValue("姓名", Me.txb_姓名.Text)
0025:
dc.Parameters.AddWithValue("附註", Me.txb_附註.Text)
0026:
dc.Parameters.AddWithValue("電話號碼", Me.txb_電話號碼.Text)
0027:
dc.Parameters.AddWithValue("稱呼", Me.txb_稱呼.Text)
0028:
dc.Parameters.AddWithValue("職稱", Me.txb_職稱.Text)
0029:
dc.Parameters.AddWithValue("雇用日期", Me.dtp_雇用日期.Value)
0030:
dc.Parameters.AddWithValue("出生日期", Me.dtp_出生日期.Value)
0031:
'利用DbAccess來執行
0032:
If db.ExecuteCmd(sql, dc.Parameters) > 0 Then
0033:
MsgBox("儲存成功!", MsgBoxStyle.Information)
0034:
Else
0035:
MsgBox("失敗!", MsgBoxStyle.Information)
0036:
End If
0037: End Sub
ADO.NET資料庫程式設計
將畫面上目前這筆資料刪除
cNorthWind.MDF
ToolStrip_btn_Delete_Click
ADO.NET資料庫程式設計
EX:CH08-02\Form1.vb
Private Sub ToolStrip_btn_Delete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles ToolStrip_btn_Delete.Click
刪除的功能比較容易處理,只需要抓取到
Dim id As Integer
頁面上目前顯示的資料錄編號,然後透過
'抓取目前顯示的資料編號
底下的SQL語法將其刪除即可
id = Val(Me.txb_員工編號.Text)
'確認
If MsgBox("確定刪除編號為" & id & "的這筆資料?", MsgBoxStyle.Question Or MsgBoxStyle.YesNo)
= MsgBoxResult.Yes Then
Dim db As New DbAccess("cNorthWind.MDF")
'建立SQL
Dim sql As String = "delete from 員工 where 員工編號=" & id
'刪除
If db.ExecuteCmd(sql) > 0 Then
MsgBox("刪除成功!", MsgBoxStyle.Information)
'顯示第一筆資料
ShowFirst()
Else
MsgBox("刪除失敗!", MsgBoxStyle.Information)
End If
End If
End Sub
ADO.NET資料庫程式設計
新增一筆資料
新增的功能對於表單上的使用者介面來說,
只是清空畫面,提供一個使用者可以輸入的
空間而已。
但是請注意,我們在使用者按下新增鈕時,
除了要清空畫面之外,還要透過Insert指令,
在資料庫中新增了一筆空白的記錄。
並且把該筆記錄帶出到畫面上…
ADO.NET資料庫程式設計
EX:CH08-02\Form1.vb
0000: Private Sub ToolStrip_btn_AddNew_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles ToolStrip_btn_AddNew.Click
0001:
Dim db As New DbAccess("cNorthWind.MDF")
0002:
Dim SQL As String = ""
0004:
'建立一個不可能重複的key值
0005:
Randomize(Microsoft.VisualBasic.Timer)
0006:
Dim tmpKey As String = "識別碼:" & Now.Ticks & Rnd()
0008:
'先新增一筆空白資料
0009:
SQL = "insert into 員工 (附註) values ('" & tmpKey & "')"
0010:
If db.ExecuteCmd(SQL) <= 0 Then
0011:
MsgBox("新增失敗", MsgBoxStyle.Critical)
0012:
Exit Sub
0013:
End If
0015:
'將剛才新增的這筆資料帶入
0016:
SQL = "select * from 員工 where 附註 like '" & tmpKey & "'"
0017:
Dim dt As DataTable = db.GetDataTable(SQL)
0018:
If dt.Rows.Count <= 0 Then
0019:
MsgBox("新增失敗", MsgBoxStyle.Critical)
0020:
Exit Sub
0021:
End If
0022:
'顯示剛才新增的那筆資料
0023:
ShowData(dt.Rows(0).Item("員工編號"))
0024: End Sub
ADO.NET資料庫程式設計
搜尋功能
搜尋的部分我們額外建立了另一張表單,使
用者可以在這個表單上輸入搜尋條件,然後
按下搜尋鈕。
當使用者按下搜尋鈕之後,該表單會直接開
啟資料庫進行搜尋動作,如果找到符合的資
料,就呼叫主頁面上的ShowData函式並傳入
記錄編號,將指定的記錄顯示出來。
EX:CH08-02\Form1.vb
Private Sub ToolStrip_btn_Search_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles ToolStrip_btn_Search.Click
Dim SearchForm As New Search
'將表單的擁有者設為 Form1
SearchForm.Owner = Me
'顯示出來
SearchForm.Show()
End Sub
ADO.NET資料庫程式設計
搜尋功能
cNorthWind.MDF
btn_search_Click (Search.vb)
ADO.NET資料庫程式設計
EX:CH08-02\Search.vb
0000: Private Sub btn_search_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles btn_search.Click
0001:
'先判斷是否沒有輸入搜尋資料
0002:
If Me.txb_addr.Text = "" And Me.txb_id.Text = "" And Me.txb_name.Text = "" And
Me.txb_tel.Text = "" Then
0003:
MsgBox("至少要輸入一個搜尋條件", MsgBoxStyle.Critical)
0004:
Exit Sub
0005:
End If
0007:
'設定一個FLAG
0008:
Dim flag As Boolean = False
0009:
Dim db As New DbAccess("cNorthWind.MDF")
0010:
Dim sql As String = "select * from 員工 where "
0011:
'組SQL字串
0012:
If Me.txb_addr.Text <> "" Then
0013:
sql += " 地址 like '" & Me.txb_addr.Text & "%'"
0014:
flag = True
0015:
End If
0016:
If Me.txb_id.Text <> "" Then
0017:
If flag = True Then sql += " and "
0018:
sql += " 員工編號 like '" & Me.txb_id.Text & "%'"
0019:
flag = True
0020:
End If
ADO.NET資料庫程式設計
EX:CH08-02\Search.vb
0021:
0022:
0023:
0024:
0025:
0026:
0027:
0028:
0029:
0030:
0032:
0033:
0034:
0035:
0036:
0037:
0038:
0039:
0040:
0041:
0042:
0043:
If Me.txb_name.Text <> "" Then
If flag = True Then sql += " and "
sql += " 姓名 like '" & Me.txb_name.Text & "%'"
flag = True
End If
If Me.txb_tel.Text <> "" Then
If flag = True Then sql += " and "
sql += " 電話號碼 like '" & Me.txb_tel.Text & "%'"
flag = True
End If
'搜尋資料
Dim dt As DataTable = db.GetDataTable(sql)
'如果沒有該筆資料
If dt.Rows.Count <= 0 Then
MsgBox("資料庫中沒有符合的資料!", MsgBoxStyle.Critical)
Exit Sub
Else
'如果找到,則呼叫主視窗中的ShowData
Dim MasterForm As Form1 = Me.Owner
MasterForm.ShowData(dt.Rows(0).Item("員工編號"))
End If
End Sub
ADO.NET資料庫程式設計
如何將照片儲存到資料庫中
ADO.NET資料庫程式設計
將照片儲存到
EX:CH08-02\Search.vb
資料庫
0000: Private Sub ToolStrip_btn_Save_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles ToolStrip_btn_Save.Click
0001:
Dim db As New DbAccess("cNorthWind.MDF")
0002:
Dim sql As String = ""
0003:
‘建立 Update 敘述(請注意當中使用到了參數  相片)
0004:
sql += "update 員工 set "
0005:
sql += " 內部分機號碼=@內部分機號碼, "
(…略…)
getByte函式:
0015:
sql += " 相片=@相片 "
傳入image屬性(也就是圖片
0016:
sql += " where 員工編號 = " & Me.txb_員工編號.Text
本身) ,會回傳一個Byte()
0017:
'我們建立了一個SQL Command物件
陣列(將其存入資料庫),內
0018:
Dim dc As New SqlClient.SqlCommand(sql)
容是剛才傳入的image物件
0019:
'並且填入 Parameters(要對應前面Update敘述的參數)
的檔案實體。
0020:
dc.Parameters.Clear()
(…略…)
0031:
dc.Parameters.AddWithValue("相片", getByte(Me.PictureBox1.Image))
0033:
'利用DbAccess來執行
0034:
If db.ExecuteCmd(sql, dc.Parameters) > 0 Then
0035:
MsgBox("儲存成功!", MsgBoxStyle.Information)
0036:
Else
0037:
MsgBox("失敗!", MsgBoxStyle.Information)
0038:
End If
ADO.NET資料庫程式設計
EX:CH08-02\Search.vb
將資料庫
中的照片顯示
出來
0000: '顯示資料
0001: Sub ShowData(ByVal id As Integer)
0002:
'連結資料庫
0003:
Dim db As New DbAccess("cNorthWind.MDF")
0004:
'抓取編號為id的資料
0005:
Dim dt As DataTable = db.GetDataTable("select * from 員工 where 員工編號=" & id)
0007:
'如果沒有該筆資料
(…略…)
0012:
'如果找到資料,則顯示出來
0013:
Me.txb_內部分機號碼.Text = dt.Rows(0).Item("內部分機號碼").ToString
(…略…)
0023:
Me.dtp_出生日期.Text = dt.Rows(0).Item("出生日期").ToString
0024:
'顯示照片
0025:
If Not IsDBNull(dt.Rows(0).Item("相片")) Then
0026:
Try
0027:
Dim tmpImageFile As String = My.Computer.FileSystem.GetTempFileName
0028:
My.Computer.FileSystem.WriteAllBytes(tmpImageFile, dt.Rows(0).Item("相片"), False)
0029:
Me.PictureBox1.Image = Image.FromFile(tmpImageFile)
0030:
My.Computer.FileSystem.DeleteFile(tmpImageFile)
0031:
Catch ex As Exception
0032:
End Try
0033:
Else
0034:
Me.PictureBox1.Image = Nothing
ADO.NET資料庫程式設計
DbAccess類別
前面說過,我們撰寫了DbAccess類別來幫我們完成資料庫存取的功能,您可
以透過這個DbAccess類別完成絕大部分的資料庫存取需求,而存取資料庫的
核心程式碼其實位於DbAccess類別當中。
ADO.NET資料庫程式設計
ADO.NET中的資料庫運作模式
ADO.NET資料庫程式設計
ADO.NET中如何對資料庫執行異動(新增、修改、刪除)
ADO.NET資料庫程式設計
ADO.NET中如何對資料庫建立連線
EX:CH08-02\DbAccess.vb
0000: Sub New(ByVal SqlExpressDbName As String)
0001:
'建立連線
0002:
If System.IO.Path.GetDirectoryName(SqlExpressDbName) = "" Then
0003:
conn = New SqlClient.SqlConnection("Data
Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\" & SqlExpressDbName & ";Integrated
Security=True;User Instance=True")
0004:
Else
0005:
conn = New SqlClient.SqlConnection("Data Source=.\SQLEXPRESS;AttachDbFilename="
& SqlExpressDbName & ";Integrated Security=True;User Instance=True")
0006:
End If
0007: End Sub
Data Source指定了資料庫的類型,在這邊我們
使用的是SQL Express資料庫,而資料庫的位
置由AttachDbFilename項目來決定。
Integrated Security=true;意思是指資料庫的使
用權限是透過系統管理,在執行程式時,會依
照目前使用者的系統帳號來嘗試開啟資料庫。
ADO.NET要與資料庫連線,必須
透過連線字串,在連線字串中可
以決定資料庫的類型、帳號密碼、
連線方式…等資訊。
ADO.NET資料庫程式設計
透過DataAdapter來讀取資料
EX:CH08-02\DbAccess.vb
SqlDataAdapter可以針對指定的資料
連線(conn)執行特定的SQL指令,並
以Fill指令,將回傳的結果(DataView)
填入dt
0000: '讀取資料
0001: Function GetDataTable(ByVal SQL As String) As DataTable
0002:
Try
0003:
Dim dt As New DataTable
0004:
Dim da As New SqlClient.SqlDataAdapter(SQL, conn)
0005:
da.Fill(dt)
0006:
0007:
Return dt
0008:
Catch ex As Exception
0009:
MsgBox("讀取資料時發生錯誤(" & SQL & ") " & vbCrLf & "錯誤訊息:" & ex.Message,
MsgBoxStyle.Critical)
0010:
Return Nothing
0011:
End Try
0012: End Function
透過SqlDataAdapter物件的Fill方法來執行SQL命令(請注意我們有傳入『conn』這個
剛才在建立好的資料庫連線物件),並且取得資料;如此一來,我們就可以取得需
要的資料,再透過對DataTable的操作來完成程式當中需要的功能。
ADO.NET資料庫程式設計
透過DataCommand來執行SQL命令
EX:CH08-02\DbAccess.vb
當我們要對資料庫做寫入的動作時,則
透過DataCommand這個物件。我們在
DbAccess類別當中,建立了ExecuteCmd
這個Method來處理。
0000: '執行命令
0001: Function ExecuteCmd(ByVal SQL As String) As Integer
0002:
Return ExecuteCmd(SQL, Nothing)
0003: End Function
0004: '執行命令
0005: Function ExecuteCmd(ByVal SQL As String, ByVal parameters As
SqlClient.SqlParameterCollection) As Integer
0006:
Try
您會發現這個
0007:
If conn.State <> ConnectionState.Open Then conn.Open()
ExecuteCmd是一個多
0008:
Dim dc As New SqlClient.SqlCommand(SQL, conn)
載的方法
0009:
'處理參數
0010:
If parameters IsNot Nothing Then
0011:
dc.Parameters.Clear()
0012:
For Each item As SqlClient.SqlParameter In parameters
0013:
dc.Parameters.AddWithValue(item.ParameterName, item.Value)
0014:
Next
0015:
End If
0016:
'執行
0017:
Return dc.ExecuteNonQuery
ADO.NET資料庫程式設計
8-5-3 透過DataCommand來執行SQL命令
EX:CH08-02\DbAccess.vb
0018:
Catch ex As Exception
0019:
MsgBox("執行命令時發生錯誤(" & SQL & ") " & vbCrLf & "錯誤訊息:" & ex.Message,
MsgBoxStyle.Critical)
0020:
Return Nothing
0021:
End Try
0022: End Function
主要的功能在程式6-21行,我們透過建立SqlCommand物件,傳入SQL命令和剛才
建立好存放在Private變數中的連結物件Conn,並且視需要(若SQL命令中有『@...
』這樣的參數)將傳入的parameter值加入第8行建立的SqlCommand(dc)物件當中,
最後再透過SqlCommand物件的ExecuteNonQuery方法來執行這段SQL指令。
ADO.NET資料庫程式設計
離線資料庫觀念
整個.NET在微軟最初建構時的核心價值觀,除了『物件導向』就是『網際網路』。
所有.NET設計架構,都是為了迎合未來開發人員,以及資訊系統在『網際網路』
上所有可能的需求,而企圖讓整個Windows平台和網際網路做出最完美的整合。
再加上XML的出現,讓資料庫的呈現方式除了傳統的『關聯式資料庫』之外,還
有其他的可能性,而ADO.NET在與XML的整合上,明顯的比ADO要進步了許多。
因此.NET Framework上的ADO.NET,在WEB資料庫程式設計的架構中,佔有相
當重要的一席之地。微軟不惜冒著讓ADO.NET和ADO在物件模型上完全不同的
風險,對資料庫物件做了相當大幅度的調整。
過去常用的資料庫存取模式是『持續連線』型的,也就是程式存取資料庫必需先
建立連線,然後持續透過這個連線來處理與資料庫有關的動作(新增、修改、刪除、
更新…等),但是這方式在今天這種多元的協同運作時代顯然不太可能,舉例來說,
我們常用的MSN、Skype、或是P2P下載軟體,其實本質上都需要一個資料庫來儲
存個人的通訊錄、名單、或是檔案資料…等。而這個資料庫顯然不是在你的電腦
上而是在遠端的伺服器裡(因為你換一台電腦用同樣的帳號都入,MSN上的通訊錄
清單依舊是最新的),在這種模式底下,資料庫中的資料,是有必要傳遞到另一台
電腦上的,並且透過遠端的電腦進行處理。
ADO.NET資料庫程式設計
離線資料庫觀念
這時候當然就不可能(也不需要)持續保持和遠端資料庫的連線,況且連線這個動
作是很耗資源的,所以沒事不要一直和資料庫連著。
而在整個ADO.NET架構底下的DataTable物件(以及DataSet物件)是可以很方便的在
網際網路上『傳遞』的。由於近代的程式慢慢開始協同運作,常有兩三個不同的
程式(不同位置、或是不同公司撰寫的..)必須共同合作的可能,而這兩三個程式可
能位於不同的網段、甚至不同的公司或國家,那這樣要怎麼交換資料呢?
微軟的ADO.NET架構也是為了因應這種SOA ( 服務導向架構 Service-Oriented
Architecture)架構而做的修改,因此我們可以將資料直接讀入存放在DataTable中,
而透過WebServices機制,直接傳遞給遠端的另一台電腦(或是另一套資訊系統),
資料可以在網際網務上傳遞無礙。
如果一來,遠端的協同運作就變的可能,傳統造價昂貴的EDI系統(電子數據交換)
或是SCM(供應鏈管理)系統,即可大幅的降低成本,這也是面對網際網路的蓬勃
發展,各家廠商所積極推動的技術。