Download presentation
Presentation is loading. Please wait.
2
曹祖聖 jimy@pcschool.com.tw 巨匠電腦顧問講師
VB 與 VB .NET 資料庫系統轉移策略 曹祖聖 巨匠電腦顧問講師
3
講師簡介 姓名:曹祖聖 Jimy Cao 郵件:jimy@pcschool.com.tw
證照:MCP, MCP+I, MCSE 4.0, MCSE 2000, MCSA, MCDBA 7.0, MCDBA 2000, MCAD, MCSD, MCT 現任: 巨匠電腦顧問講師 台灣微軟特約講師 光明頂軟體股份有限公司研發顧問 凌天科技股份有限公司技術顧問 明陽資訊股份有限公司技術顧問 大台中人力銀行特約講師 專業電腦圖書作家 電腦雜誌專欄作家
4
講師簡介 經歷: 智慧工作室程式設計師 一級棒資訊股份有限公司系統分析師、專案經理 華彩教育訓練中心講師 資策會教育訓練中心講師
巨匠電腦認證中心專任講師 微軟 TechEd 2000 國際研討會講師 (2場) 微軟 TechEd 2001 國際研討會講師 (1場, 全國第二名) 微軟 PDC 2002 國際研討會講師 (2場, 全國第一名) 微軟 Windows 2000 實力札根研討會講師 (2場) 微軟 DevCon 專業 .NET 開發技術研討會講師 (8場) 微軟 Visual Studio .NET 中文版上市發表會 (全省巡迴 4 場) 微軟 TechEd 2002 國際研討會講師 (2 場) 微軟 Windows Server 2003 中文版上市發表會 (全省巡迴 4 場) 東海、成功、長榮 … 等大專院校資訊技能生涯規劃講座講師
5
議程大綱 語言的差異與轉換所需注意事項 ADO 與 ADO .NET 轉移 VB .NET 中對於舊版 ADO 的支援
資料處理架構與效能的改變
6
議程大綱 語言的差異與轉換所需注意事項 ADO 與 ADO .NET 轉移 VB .NET 中對於舊版 ADO 的支援
資料處理架構與效能的改變
7
一般語法的改變 (一) 預設屬性 (Default Properties)
物件參考 (Reference) 指派 VB 6.0 : Set txtPassword = txtName VB .NET : txtPassword = txtName VB .NET 中不再支援預設屬性 VB 6.0 : txtPassword = txtName VB .NET : txtPassword.Text = txtName.Text 具參數的物件可省略屬性 RS.Fields.Item(No).Value RS.Fields(No).Value RS.Fields(No)
8
一般語法的改變 (二) 副程式呼叫與傳值/傳址參數
副程式呼叫不論是否有參數都要加括號 VB 6.0 : CheckSize No, 5 Call CheckSize(No, 5) VB .NET : CheckSize(No, 5) Call CheckSize(No, 5) VB .NET 副程式參數預設 ByVal Dim Y As Integer Y = 5 Call MyFunc(Y) Call MsgBox(Y) Sub MyFunc(X As Integer) X = 10 End Sub
9
一般語法的改變 (三) 變數宣告 (一) 變數宣告一定要加型態 VB .NET 不再支援 Variant 型態 連續變數宣告,型態相同
VB 6.0 : Dim X ‘ X 是 Variant 型態 VB .NET : Dim X As Integer VB .NET 不再支援 Variant 型態 VB 6.0 : Dim X As Variant VB .NET : Dim X As Object 連續變數宣告,型態相同 VB 6.0 : Dim X, Y As Integer ‘ X 是 Variant VB .NET : Dim X, Y As Integer ‘ X, Y 都是 Integer
10
一般語法的改變 (三) 變數宣告 (二) VB .NET 變數預設值設定 VB .NET 支援區塊等級 (Block-Level) 變數
Dim X As Integer = 10 VB .NET 支援區塊等級 (Block-Level) 變數 While No < 10 Dim X As Integer … End While 變數生命週期僅止於區塊內 If … Else … End If, For … Next, Do … Loop, While … End While, Select … Case … End Select
11
一般語法的改變 (四) Boolean 運算 非零值表示 True
If CBool(2) Then … AndAlso 與 OrElse 運算子 (short-circuiting) Dim X As Integer Dim Y As Integer X = 0 Y = 2 If X <> 0 And Y / X = 2 Then ‘ 兩者都會檢查 … If X = 0 Or Y = 0 Then ‘ 兩者都會檢查 If X <> 0 AndAlso Y / X = 2 Then ‘ X = 0 即不成立 If X = 0 OrElse Y = 0 Then ‘ X = 0 即成立
12
副程式的改變 (一) Optional 參數 Optional 參數必須指定型態與預設值 VB 6.0 :
Sub Test(Optional ByVal X) If IsMissing(X) Then … End Sub VB .NET : Sub Test(Optional ByVal X As Integer = 0) If X = 0 Then End If
13
副程式的改變 (二) 離開 Function 並傳回值
VB .NET : Return X VB .NET 支援 Return 敘述 (Sub 或 Function) VB 6.0 : Function Test(ByVal X As Integer) As Integer Dim I As Integer For I = 2 To X If X / I = 0 Then Test = X Exit Function End If Next End Sub
14
副程式的改變 (三) ParamArrays
VB .NET 中的 ParamArrays 參數 使用 ByVal 傳遞 ( VB 6.0 是 ByRef ) 可以為任何型態 ( VB 6.0 是 Variant ) 不可以與 Optional 共用 Sub Test(ByVal ParamArray X( ) As Object) Dim I As Integer For I = X.GetLowerBound(0) To X.GetUpperBound(0) MsgBox(X(I)) Next End Sub
15
副程式的改變 (四) 將物件屬性當成參數 VB 6.0 中不論使用 ByVal 或 ByRef 傳遞物件屬性,在副程式中均不會修改到該屬性的值 VB .NET 中使用 ByRef 傳遞物件屬性,在副程式中可以修改該屬性的值 Sub Test(ByRef X As String) X = "Modified !!" End Sub txtName.Text = "Hello !!" Call Test(txtName.Text) Call MsgBox(txtName.Text)
16
陣列的改變 Array 陣列註標一律由 0 開始,並可設定初始值
Dim X(2) As Integer ‘ 註標 0, 1, 2 共三個整數 Dim Y() As Integer = {1, 2, 3, 4, 5} VB 6.0 : Option Base 2、Dim X(2 To 10) As Integer 陣列指派預設為 ByRef (VB 6.0 預設為 ByVal),如要拷貝陣列 (ByVal),必須使用 Clone 方法 Dim X() As Integer = {0, 1, 2} Dim Y() As Integer Y = X Y(1) = 100 MsgBox( X(1) ) Y = X.Clone()
17
資料型別的改變 (一) 資料的配置 所有變數都是物件,都有屬性與方法 整數型別 字串型別
資料型別的改變 (一) 資料的配置 所有變數都是物件,都有屬性與方法 整數型別 字串型別 一律 Unicode 編碼 不支援固定長度字串宣告 ( Dim S As String * 10) Decimal 型別取代 VB 6.0 中的 Currency 型別 Object 型別取代 VB 6.0 中的 Variant 型別 版本 Short Integer Long VB 6.0 8 bits 16 bits 32 bits VB .NET 64 bits
18
語法的效能比較
19
資料型別的改變 (二) 型別檢查與型別轉換 嚴格型別檢查 型別轉換 Dim X As Integer, S As String = "12"
資料型別的改變 (二) 型別檢查與型別轉換 嚴格型別檢查 Dim X As Integer, S As String = "12" X = S ‘ 型別不同,在 Option Restrict On 下會錯 Option Restrict Off ‘ 取消嚴格型別檢查 型別轉換 使用型別轉換函數 S = CStr(No) 使用物件方法 S = No.ToString() ‘ 數字轉字串 No = Integer.Parse(S) ‘ 字串轉數字
20
資料型別的改變 (三) 自訂型別 VB 6.0 VB .NET Private Type Student Name As String
資料型別的改變 (三) 自訂型別 VB 6.0 Private Type Student Name As String Address As String Age As Integer End Type VB .NET Structure Student Dim Name As String Dim Address As String Dim Age As Integer End Structure
21
資料型別的改變 (四) 自訂型別變數預設值的指定
資料型別的改變 (四) 自訂型別變數預設值的指定 Structure Student Dim Name As String Dim Age As Integer Sub New(ByVal vName As String, ByVal vAge As Integer) Me.Name = vName Me.Age = vAge End Sub End Structure Private Sub Button1_Click( … ) Handles Button1.Click Dim Peter As New Student("王小明", 25) MsgBox(Peter.Name + vbCrLf + Peter.Age.ToString())
22
其它改變 新增運算子 其它 命名空間 (Namespace) 繼承 (Inheritance) 多載 (Overloading)
A += 2 ‘ A = A + 2 +=, -=, *=, /=, \= (整除) , ^= (次方) , &= (字串相加) 其它 命名空間 (Namespace) 繼承 (Inheritance) 多載 (Overloading) 執行緒 (Free Threading) Garbage Collection
23
議程大綱 語言的差異與轉換所需注意事項 ADO 與 ADO .NET 轉移 VB .NET 中對於舊版 ADO 的支援
資料處理架構與效能的改變
24
.NET Framework 中 ADO 與 XML 架構
使用 VS .NET 整合環境 精靈或程式碼產生 XSL/T, X-Path, etc DataSet XmlData- Document 同步 DataAdapter XmlReader DataReader .NET Data Provider Command Connection
25
Connection 物件 SqlConnection OleDbConnection
conn.ConnectionString = "User ID=sa; Password=; Server=localhost;Database=Northwind" OleDbConnection conn.ConnectionString = "Provider=SQLOLEDB; User ID=sa; Password=; Data Source=localhost; Initial Catalog=Northwind" 只能夠連接 Microsoft SQL Server 效能最佳化 需引用 System.Data.SqlClient 可以透過 OLE DB 連接不同的資料庫 應用範圍最廣 需引用 System.Data.OleDb 一樣可以連接 Microsoft SQL Server
26
如何建立資料庫連線 使用資料庫連線的步驟 Dim conn As New OleDbConnection() 建立資料庫連線物件
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; User ID=Admin; Password=123; Data Source=C:\Northwind.mdb" conn.Open() conn.Close() 建立資料庫連線物件 設定連線字串 開啟資料庫連線 : 關閉資料庫連線
27
如何處理本機 Transaction 處理本機 Transaction 的步驟 conn.Open()
Dim trans As SqlTransaction trans = conn.BeginTransaction() If … Then trans.Rollback() If … Then trans.Commit() conn.Close() 啟始一個 Transaction : Transaction 失敗時 Transaction 成功時
28
ADO RecordSet ADO.NET RecordSet ADO.NET Forward Only Cursors
DataReader DataSet Client Cursors Server Cursors XmlDataDocument
29
Cursors Forward & Read Only Cursor
ADO : Forward Only Recordset ADO .NET : DataReader Dim sql As String = "select PName, Qty from MyOrders" Dim cmd As SqlCommand = new SqlCommand(sql, conn) Dim dr As SqlDataReader = cmd.ExecuteReader() Do While dr.Read() Dim pname As String = dr.GetString(0) Dim qty As Integer = dr.GetInt32(1) Console.WriteLine("{0}, {1}", pname, qty) Loopa
30
多筆資料的瀏覽 DataReader
31
Cursors Dynamic、Static & Keyset Cursor
ADO .NET : 使用 Command、DataSet 未來將支援 ResultSet Dim rs As SqlResultSet = cmd.ExecuteResultSet( ResultSetOptions.Scrollable + ResultSetOptions.Updatable) Do While rs.Read() if rs("姓名“) = "王小明" Then rs("姓名“) = "王大炮" Loop rs.ReadLast() Do While ( rs("地址“) <> "台中市中山路27號1樓" And Not rs.Bof() ) rs.ReadPrevious() rs("地址“) = "台中市中山路27號5樓" rs.Update()
32
Server Cursors ADO.NET: ADO 中的 Server cursors 適合用在:
著重在離線資料的存取,適合用在 Internet 上 ADO 中的 Server cursors 適合用在: Client/Server 架構中做資料繫結 單筆資料的修改 OLTP 式的資料存取 (資料鎖定的時間長) 克服同一個 Connection 無法連續執行多個指令 (同一個 Batch) 的限制 DataSet
33
Server Cursor ADO .NET 的解決方案
單筆資料的修改 使用 DataSet 支援 Transaction 另外使用 Command OLTP 式的資料存取 使用 Command, DataReader, Transaction 最好使用 Stored Procedure 同一個 Connection 連續執行多個指令 使用 Dynamic SQL 語法
34
Command 物件 SqlCommand 與 OleDbCommand 支援多種 SQL 命令 允許加入參數 (Parameters)
DCL : GRANT, REVOKE, DENY DDL : CREATE, ALTER, DROP DML : SELECT, INSERT, DELETE, UPDATE 其它 : Stored Procedure, CURSOR, … 允許加入參數 (Parameters)
35
單筆資料的修改 ExecuteNonQuery 方法
建立一個 Command 物件 建立參數物件 設定參數值 將參數加入 Command 物件 執行 SQL 語法 Dim cmd As New SqlCommand("update… where conn) Dim param As New TypeOf(Integer)) param.Value = 12 cmd.Parameters.Add(param) Dim rowEffects As Integer = cmd.ExecuteNonQuery()
36
單筆資料的查詢 ExecuteScalar 方法
建立一個 Command 物件 建立參數物件 設定參數值 將參數加入 Command 物件 執行 Command 並取得結果 Dim sql As String = "select cid from… where Dim cmd As New SqlCommand(sql, conn) Dim param As New TypeOf(Integer)) param.Value = 12 cmd.Parameters.Add(param) Dim myCID As Integer = cmd.ExecuteScalar()
37
執行 Stored Procedure CommandType.StoredProcedure
設定使用連線 設定命令名稱 設定 CommandType 建立參數 執行 Stored Procedure Dim cmd As New SqlCommand() cmd.Connection = conn cmd.ComandText = "DeleteOrder" cmd.CommandType = CommandType.StoredProcedure orderID) Dim rowEffects As Integer = cmd.ExecuteNonQuery()
38
Web Form 控制項資料繫結 將 Web Form 控制項 DataSource 屬性繫結到 DataRead 物件
如果控制項一次只能顯示資料表中的單一欄位,則除了 DataSource 屬性之外,還要加設 DataTextField 和 DataValueField 屬性 最後一定要執行控制項的 DataBind 方法,將資料取回控制項中,進行繫結
39
Stored Procedure Web Form Data Binding
40
Dynamic SQL cmd.CommandText = “ DECLARE mycursor SCROLLABLE CURSOR FOR SELECT * FROM Customers" cmd.ExecuteNonQuery() cmd.CommandText = "OPEN mycursor" cmd.ExecuteNonQuery( cmd.CommandText = "FETCH NEXT FROM mycursor" SqlDataReader dr =cmd.ExecuteReader( // 讀取並處理資料 dr.Close() cmd.CommandText = "FETCH ABSOLUTE 5 FROM mycursor" cmd.CommandText = "UPDATE Customers set ContactName = ‘Luca Bolognese’ WHERE CURRENT OF mycursor" cmd.CommandText = "CLOSE mycursor; DEALLOCATE mycursor"
41
Dynamic SQL
42
議程大綱 語言的差異與轉換所需注意事項 ADO 與 ADO .NET 轉移 VB .NET 中對於舊版 ADO 的支援
前端資料處理架構與效能的改變
43
如何使用舊版 ADO ADO 2.x 版的解決方案 舊版 ADO Data Provider 依舊可以使用 自行引用下列空間,並撰寫程式碼
ADODB Microsoft.VisualBasic.Compatibility.VB6 MSAdodcLib MSDATASRC Stdole 建議使用升級精靈
44
VB 升級精靈
45
議程大綱 語言的差異與轉換所需注意事項 ADO 與 ADO .NET 轉移 VB .NET 中對於舊版 ADO 的支援
資料處理架構與效能的改變
46
離線資料的存取 DataAdapter 與 DataSet 的關係 如何取得 DataSet DataSet 的結構
WinForms 控制項資料繫結的方式
47
DataAdapter 與 DataSet DataSet 與資料庫之間透過 DataAdapter 進行存取動作 DataAdapter
SelectCommand InsertCommand UpdateCommand DeleteCommand Fill DataSet 資 料 庫 Update
48
如何取得 DataSet 透過 DataAdapter 取得 DataSet 資料
Dim cmd As New SqlCommand() cmd.Connection = conn cmd.ComandText = "select * from Customers" Dim da As New SqlDataAdapter() da.SelectCommand = cmd Dim s As New DataSet("Customers") da.Fill(ds) Dim da As New SqlDataAdapter( "select * from Customers", conn ) 建立一個 Command 用來執行 SELECT 語法 建立 DataAdapter 物件 設定 SelectCommand 建立一個 DataSet 物件 使用 DataAdapter 物件的 Fill 方法 填滿 DataSet
49
DataSet 的結構 使用 Tables(表格號碼) 或 Tables("表格名稱") 來引用 Tables 中的任何一個表格。 (Tables.Count 可以取得表格數目) 每一個 DataSet 中的表格都是一個 DataTable 物件 DataTable 可以包含多筆資料列 (Row),組成 Rows 集合 使用 Rows(列號碼) 來引用 Tables 中的任何一個表格。 (Rows.Count 可以取得資料總筆數) 透過欄位號碼或欄位名稱來存取 DataRow 的資料 每一個 DataRow (每一筆記錄) 中包含了多個欄位 DataSet 可以包含多個表格 (Table),組成 Tables 集合 Rows 集合中的每一筆資料記錄都是一個 DataRow 物件 DataSet Tables DataTable Tables[0] Tables[1] Tables[2] Tables[3] : DataRow Rows Rows[0] Rows[1] Rows[2] : AB (04) 男 王小明 血型 電話 性別 姓名 3 2 1 Dim row As DataRow = ds.Tables(0).Rows(3) Dim name As String = row(0) Dim phone As String = row("電話")
50
如何瀏覽 DataSet 中的資料 使用 For Each 迴圈瀏覽 DataSet 資料 Dim cust, ord As DataRow For Each cust In ds.Tables(0).Rows Console.WriteLine( "\n客戶: {0}", cust("Name") ) For Each ord In cust.GetChildRows("odr") Console.Write( "訂單編號: {0}", ord("id") ) Console.Write( "\t數量:{1}\n", ord("qty") ) Next Next 使用 For 迴圈瀏覽 DataSet 資料 For c = 0 To ds.Tables(0).Columns.Count - 1 Dim dc As DataColumn = ds.Tables(0).Columns(c) Console.Write("{0}\t", dc.ColumnName) Next For r = 0 To ds.Tables(0).Rows.Count - 1 cName = ds.Tables(0).Rows(r)("客戶名稱") cAddress = ds.Tables(0).Rows(r)("地址") Console.WriteLine("\n{0}\t{1}", cName, cAddress) Next
51
DataList + DataSet
52
如何將 DataSet 中的資料 更新至資料庫
Dim adapter As New SqlDataAdapter() Dim delete As New SqlCommand("DeleteOrder",cnn) delete.CommandType=CommandType.StoredProcedure Typeof(Integer)).SourceColumn="OrderID" adapter.DeleteCommand = delete Dim insert As New SqlCommand("AddOrder",cnn) insert.CommandType=CommandType.StoredProcedure TypeOf(Integer)).SourceColumn="OrderID" TypeOf(Integer)).SourceColumn="CustomerID" TypeOf(DateTime)).Value = DateTime.Now adapter.InsertCommand = insert Dim update As New SqlCommand("UpdateOrder",cnn) update.CommandType=CommandType.StoredProcedure TypeOf(Integer)).SourceColumn="OrderID" TypeOf(Integer)).SourceColumn="CustomerID" adapter.UpdateCommand = update adapter.Update(ordersTable) Dim da As = New SqlDataAdapter ("select * from Customers", conn) : : Dim cb As New SqlCommandBuilder(da) da.InsertCommand = cb.GetInsertCommand da.UpdateCommand = cb.GetUpdateCommand da.DeleteCommand = cb.GetDeleteCommand da.Update(ds)
53
Win Form 控制項資料繫結 指定將 DataSet 中的 Members.Name 欄位繫結到 Text 屬性 指定將 DataSet 中的 Members.Size 欄位繫結到 Width 屬性 繫結到 txtName 文字方塊 使用 Binding 物件進行資料繫結 控制項的任何屬性都可以繫結到資料庫的 任何欄位,可且可以繫結多個屬性 Dim bdText As New Binding("Text", ds, "Members.Name") Dim bdWidth As New Binding("Width", ds, "Members.Size") txtName.DataBindings.Add(bdText) txtName.DataBindings.Add(bdWidth)
54
BindingManager 用來控制 Binding 的相關動作 Dim bm As New BindingManagerBase()
bm = BindingContext(ds, "Members") bm.Position = 0 ‘ 第一筆 bm.Position = bm.Position + 1 ‘ 下一筆 bm.Position = bm.Count – 1 ‘ 移到最後一筆 bm.AddNew() ‘ 新增一筆 bm.EndCurrentEdit() ‘ 結束編輯 bm.RemoveAt( bm.Position ) ‘ 刪除一筆
55
DataBinding BindingManager
56
前端 DataSet 資料表關聯 DataSet 中各 DataTable 之間可以建立關聯性
Dim dr As New DataRelation( “關聯名稱” , Primary Key / Parent 欄位 , Foreign Key / Child 欄位 ) DataSet 中各 DataTable 之間可以建立關聯性 Primary Key Parent Column Foreign Key Child Column DataRelation 物件與 Relations 集合 Dim dr As New DataRelation( "MemberToOrders" , ds.Tables("Members").Columns("會員編號") , ds.Tables("Orders").Columns("會員編號") ) ds.Relations.Add(dr)
57
GetChildRows 方法 透過 DataSet 中 Parent 表格中每一筆資料 DataRow 的 GetChildRows 方法,可以取得所關聯的 Child 表格中的資料。 Dim dr As DataRow = ds.Tables("Members").Rows(0) Dim child() As DataRow = dr.GetChildRows("MemToOdrs") For I = 0 To child.Length - 1 Dim pid As Integer = child( I )( "產品編號" ) Dim qty As Integer = child( I )( "數量" ) Console.Write("{0}\t{1}\n", pid, qty) Next
58
DataRelation
59
ADO .NET 十大技巧
60
如何在設計時期指定 Metadata 狀況: 為了取得 Metadata 資料,必須往返資料庫 ,降低執行效率
DataReader : 嚴格型別的資料讀取方式 DataSet 載入資料,但是不要載入 Schema 指定適當的 XmlReadMode XmlReadMode.IgnoreSchema Data Adapter 用程式指定 INSERT / UPDATE / DELETE commands 用程式指定 Command 的參數 避免使用 CommandBuilder 指定 Primary Key
61
如何更新資料至 DataSet ? 狀況: 資料庫中的資料可能有變動,希望 將最新的資料更新到 DataSet 中 解決方式:
使用 Adapter.Fill() 方法 會蓋掉 DataSet 中原本已修改的資料 我想要取得資料庫中最新的資料,但是也想要保留 DataSet 中已修改部份 Dim newDs As New DataSet() da.Fill(newDs) ds.Merge(newDs, true)
62
如何撰寫支援任何一種 .NET Data Provider 的程式
狀況: 針對 OleDb, Sql, Odbc … 等 .NET Data Providers,所需的相關物件 都不同,例如 Command, DataAdapter, … 解決方式: 使用 IDbConnection 介面 使用 IDbConnnection 的 CreateCommand() 方法取得 IDbCommand 自訂 Data Provider
63
支援多種 .NET Data Providers
64
如何一次讀取多表格至 DataSet ? 狀況: 希望一次讀取多個表格至 DataSet 解決方式:
使用批次 SQL 查詢或執行 Stored Procedure Dim da As New SqlDataAdapter( "SELECT * FROM customers; SELECT * FROM orders",conn) da.Fill(ds) 使用 ExecuteXmlReader 讀取 SQL Server 傳回 的 XML Dim cmd As New SqlCommand( "SELECT Customers.*, Orders.* FROM Customers, Orders " & "WHERE Customer.State='CA' AND " & "Customer.CustID=Order.CustID FOR XML AUTO", conn) Dim xr As XmlReader = cmd.ExecuteXmlReader() ds.ReadXml(xr, XmlReadMode.Fragment)
65
如何對應 DataAdapter 所傳回來的 DataSet 中每一個表格的名字 ?
狀況: 當多個表格由 DataAdapter 傳回 DataSet 時 ,預設的表格名字是 "Table1", "Table2", … 解決方式: Dim da As New SqlDataAdapter( "SELECT * FROM customers; SELECT * FROM orders",conn) da.TableMappings.Add("Table1", "客戶資料") da.TableMappings.Add("Table2", "訂單資料") da.Fill(ds)
66
如何傳遞 Null 值給 Command 的 Parameter ?
狀況: 無法使用 null, Nothing, "" 當做 Null 值 傳至 Command 的 Parameter,不傳值 也不行 !! 解決方式: 使用 DBNull.Value Dim param As New SqlParameter() param.Value = DBNull.Value
67
如何避免 DataReader 自動預讀資料 ?
解決方式: Dim cmd As New SqlCommand ("Select * from Employees ", conn) Dim dr As DataReader = cmd.ExecuteReader (CommandBehavior.SequentialAccess) Do While dr.Read() // 依序讀取每一個欄位 For I = 0 To dr.FieldCount – 1 Console.Write( "\t {0}", dr( I ) ) Next Console.WriteLine() Loop
68
如何在關閉 DataReader 時自動 關閉對應的 Connection ?
解決方式: Private Function GetCategories() As DataReader Dim cmd As New SqlCommand ("Select * from Categories", conn) Dim dr As DataReader = cmd.ExecuteReader (CommandBehavior.CloseConnection) Return dr End Function
69
如何處理新增資料時,不同用戶端 Primary Key 衝突的問題 ?
狀況: 不同用戶端可能產生同樣的 Primay Key 欄位值,在新增至 DataSet 或 資料庫時,就會產生錯誤 解決方式: 使用 GUID 格式的 Primary Key 欄位 用戶端可以自行產生 保證不會重覆 更新至資料庫時,不需要修改 Primary Key 值 關聯的子表格 Foreign Key 欄位也不需要修改 Primary Key 欄位長度比較長 (128 bits)
70
如何新增包含自動編號限制的 Primary Key 的資料 ?
狀況: 由於 DataSet 中針對自動編號欄位,預設 由 0 開始累加,每次加一,然而常常與 原本 DataSet 中已存在的資料相衝突 !! 解決方式: Dim cmd As New SqlCommand( "SELECT TOP 1 ( ID + 1 ) AS ID FROM Members " & ORDER BY ID DESC", conn) Dim dr As SqlDataReader = cmd.ExecuteReader() If dr.Read() Then ds.Tables(0).Columns(0).AutoIncrementSeed = dr.GetInt32(0) End If
71
將含有自動編號的資料新增至資料庫 void da_RowUpdating(object sender, SqlRowUpdatingEventArgs e) { If e.StatementType = StatementType.Insert Then e.Status = UpdateStatus.SkipCurrentRow conn.Open() da.InsertCommand.CommandText += ";select as ID" SqlDataReader dr = da.InsertCommand.ExecuteReader() if dr.Read() e.Row( "ID" ) = dr.GetValue(0) End If dr.Close() conn.Close() }
72
處理自動編號欄位
73
總結 ADO.NET… 提供程式開發人員超強的資料存取機制 支援舊版 ADO 先進的資料存取物件 開放式架構 提供完善的升級精靈
.NET Data Providers 提供各類型資料庫的連結 DataSet 支援離線資料的存取 開放式架構 可以在設計時期進行 DataSet Schema 的存取 支援舊版 ADO 提供完善的升級精靈 提供舊版資料繫結的解決方案
74
相關資訊 MSDN 技術白皮書 ADO.NET for the ADO Programmer: /dndotnet/html/ADONETProg.asp ADO.NET Best Practices: /dndotnet/html/ADONETBest.asp The .NET Show: ADO.NET: /Episode017/default.asp
75
參考書目 ASP.NET 實戰 For VB.NET (松崗) ASP.NET 實戰 For C# (松崗)
Visual Basic.NET學習範本 (松崗) Visual Basic.NET程式設計經典 (6月 松崗) Visual C#程式設計經典 (10月 松崗) Visual Basic.NET資料庫實戰 (未定 松崗) Visual C++ 學習範本 (未定 松崗)
76
© 2001 Microsoft Corporation. All rights reserved.
Similar presentations