Chương 6 : Các vấn đề về cách bảoquảntàiliệu _ Advance Data Access Issues Database, nơi chứa những tàiliệu mà chúng ta giao cho nó gìn giử. Ðơn giản như vậy đó !. Nhưng nếu ai cũng vào được để đánh cắp hay sửa đổi chi tiết thì sao ? Chuyện sẽ trở nên phức tạp liền. Cho nên trong phần này chúng tôi sẽ nói làm sao để giử gìn tàiliệu tốt hơn. Chương 6 _ Phần 1 _ Ðoạn 1 : Understanding SQL Server Security Thế nào là SQL Server Security ? Khi các bạn viết ứng dụng cho client, các bạn phải kế hoạch ứng dụng đó được nối liền với Server như thế nào ? Ai có thể vào được Database (who can access Database ?), làm sao để vào Database (how to access Database ?). SQL Server giúp các bạn làm việc này bảo bằng 2 modes • Standard security mode : Người xử dụng không cần phải phụ thuộc vào hệ thống Windows NT • Integrated security mode : Người xử dụng phải ở trong hệ thống Windows NT Standard security mode là default security mode của SQL Server. Standard mode xử dụng SQL Server security model cho mỗi connection vào trong Database. Ở những nơi gọi là non-trusted environments (không an toàn) như internet chẳng hạn, thì standard mode giúp các bạn việc thông thương với Database dể dàng. Với standard mode, người xử dụng không cần phải thông qua Windows NT Server trước khi được nối liền với Database. Người xử dụng thông qua SQL Server trên hệ thống internet và phải có các security features (các điều kiện để bước vào kho như userID, password, chổ nào trong kho .). System Administrator hoặc là Database Owner (người chịu trách nhiệm gìn giử hệ thống network và tài liệu) làm các userID, password, nhóm người xử dụng cho mỗi Database trong Server, để khi người xử dụng muốn vào kho tàiliệu để làm việc, họ phải thỏa mản các điều kiện vào kho, userID và password phải trùng hợp . Do đó, khi viết ứng dụng các bạn phải làm một trong 3 việc sau đây : 1. Hard-code all connection information. Viết code cho tất cả các connection. 2. Prompt the user for some information and hard-code the rest. Yêu cầu người xử dụng điền một số chi tiết và viết các phần còn lại. 3. Prompt the user for all information. Yêu cầu người xử dụng phải hoàn chỉnh tất cả các yêu cầu để thông thương với Data source. Integrated security mode là hệ thống security hợp nhất, xử dụng bởi Windows NT kiểm soát toàn bộ các connection của các ứng dụng nối liền vào Database. Cả hệ thống network đều phải ở trên đường Windows NT chạy qua và từ chuyên nghiệp gọi là trusted connections hay là trusted environment. Hay nói cách khác là ứng dụng của các bạn phải được cài đặt trên Windows NT. Do đó, intergrated security yêu cầu ứng dụng phải ở Windows NT platform mới có thể thực hiện connection được. Intergrated (hợp nhất) security mode có thể biến đổi password (encrypted password) khi thực hiện connection, như vậy hệ thống gìn giử tàiliệu sẽ khó xâm nhập hơn. Và chỉ cần 1 password thôi nhưng người xử dụng có thể thông qua vừa Windows NT, vừa SQL Server. Ðó là lý do vì sao gọi là Intergrated (hợp nhất) security mode. Sau đây là click event trình bày lối nối liền vào SQL Server với điều kiện là người xử dụng phải trả lời đúng userID và password. Standard security mode hay Intergrated security mode tùy thuộc vào system administration nơi làm việc của các bạn. Sub cmdConnect_Click() Dim sUsername As string Dim sPassword As string Dim cnStateUBookstore As Connection Set cnStateUBookstore = New Connection sUsername = InputBox("Please enter your user name:") sPassword = InputBox("Please enter your password:") With cnStateUBookstore .Provider = "SQLOLEDB" .ConnectionString = "User ID=" & sUsername & _ ";Password=" & sPassword & _ ";Data Source=MSERIES1;" & _ "Initial Catalog=StateUBookstore" .Open End With End Sub Chương 6 _ Phần 2 : Xử dụng Cursor Khi một Recordset object được tạo thành, thì theo mục đích của ứng dụng, một số tàiliệu nhất định sẽ được xử dụng thường xuyên dựa trên SQL query statement. Số tàiliệu này gọi là nhóm tài liệu. Nhóm tàiliệu được xử dụng thường xuyên này gọi là cursor, bởi vì nó biểu hiện một nơi nhất định nào đó trong Database mà ứng dụng xài thường xuyên. Cursor không hẳn nghĩa là nơi mà khi bạn bấm chuột hay bấm nút Enter trên màn ảnh máy vi tính thì công việc đó sẽ được thi hành. Như vậy, với SQL statement, cursor chúng ta sẽ hiểu là một nhóm tàiliệu được xử dụng thường xuyên (specific records based on a SQL query) Có 4 thể loại cursor (cursor type) và 2 nơi chứa đựng (cursor location). Mời các bạn theo dỏi, chúng tôi sẽ trình bày tiếp sau đây. Chương 6 _Phần 2 _ Ðoạn 1 : Choosing Cursor Type Bốn thể loại cursor trong recordset object là : forward-only, static, dynamic và keyset. Hai nơi mà cursor có thể đặt vào là Server side và Client side. Mời các bạn theo dỏi các tính chất của thể loại và nơi chốn của cursor sau đây, để về sau, các bạn có thể quyết định nên xử dụng thể loại nào ? Forward-Only Cursors : là thể loại đương nhiên có sẳn trong recordset object (default recordset cursor type). Trong thể loại này chứa đựng MoveNext method khi bạn tìm đọc tài liệu. Và vì thế cho nên khi các bạn thêm vào các method khác để tìm đọc tàiliệu thì sẽ bị run-time errors. Thể loại này thích hợp cho trường hợp bạn có số lượng nhỏ tàiliệu mà thôi. Keyword cho thể loại này là adOpenForwardOnly. Ðây là click-event biểu diển việc làm là khi mở bản tàiliệu ra, thể loại Forward-Only Cursor đồng thời có mặt trong recordset object : Sub cmdOpenRecordset_Click() Dim rsPublishers As Recordset Set rsPublishers = New Recordset With rsPublishers .Open "SELECT pub_id FROM Publishers", cnStateUBookstore, _ adOpenForwardOnly End With End Sub Static Cursors : Với thể loại này, nó không cập nhật hóa các thay đổi về tàiliệu khi có người xử dụng thay đổi chi tiết trong bản tài liệu. Theo thứ tự, thì các chi tiết trong bản tàiliệu sẽ được cập nhật hóa sau khi recordset mở ra để xử dụng. Thí dụ như ứng dụng của bạn xử dụng static cursor type, bạn làm việc với một chi tiết (record) trong bản tàiliệu (recordset), đồng thời cùng lúc có người xử dụng thay đổi chi tiết đó (chi tiết mà bạn đang cần) thì chi tiết mà Database cung cấp cho bạn thấy sẽ là chi tiết củ chưa cập nhật hóa, chứ không phải là chi tiết mới. Khi bạn đóng recordset lại và khi bạn mở ra, thì lúc đó, bạn sẽ thấy chi tiết mà được sửa đổ sẽ cập nhật. Các bạn xử dụng thể loại này khi các bạn cần nhiều cách thức tìm kiếm tàiliệu uyển chuyển (flexible navigation) và không cần thiết phải nhìn thấy tàiliệu cập nhật. Keyword cho thể loại này là adOpenStatic. Sau đây là click event trong đó xử dụng thể loại static cursor Sub cmdOpenRecordset_Click() Dim rsPublishers As Recordset Set rsPublishers = New Recordset With rsPublishers .Open "SELECT pub_id FROM Publishers", cnStateUBookstore, _ adOpenStatic End With End Sub Dynamic cursor : Dynamic cursor được xử dụng nhiều nhất trong các thể loại cursors. Bởi vì dynamic cursor có thể cập nhật hóa các chi tiết trong bản tàiliệu ngay lập tức sau khi có sự thay đổi. Thí dụ như các bạn làm việc với 2 records trong một recordset, một trong 2 chi tiết đó bị xóa bỏ đi và chi tiết khác thì được thay đổi, thì dynamic cursor sẽ trình bày cho các bạn thấy một chi tiết mới đã được cập nhật hóa và các bạn sẽ không thấy chi tiết đã xóa bỏ đi rồi. Do đó, thể loại dynamic cursor rất thích hợp cho các ứng dụng làm việc với các chi tiết cần phải cập nhật ngay tức thì ( từ chuyên nghiệp gọi là live Data). Keyword cho thể loại này là adOpenDynamic. Sau đây là click event trình bày làm sao để cài đặt dynamic cursor vào trong recordset. Sub cmdOpenRecordset_Click() Dim rsPublishers As Recordset Set rsPublishers = New Recordset With rsPublishers .Open "SELECT pub_id FROM Publishers", cnStateUBookstore, _ adOpenDynamic End With End Sub Keyset cursor : keyset cursor là thể loại nằm giửa static và dynamic cursor. Giống như static cursor, keyset cursor không phải lúc nào cũng chấp nhận sự thay đổi của tài liệu, và chi tiết mới trong bản tàiliệu sẽ không được trình bày cho tới khi bản tàiliệu được mở trở lại sau khi đóng. Giống dynamic cursor là keyset cursor cập nhật ngay những thay đổ trong recorset. Các bạn xử dụng thể loại này khi các bạn cần theo dỏi các chi tiết mà mình phải sửa đổi nhưng không cần thiết phải nhìn thấy các record bị xóa đi hay thêm vào. Keyword cho thể loại này là adOpenKeyset. Sau đây là click event nói về cách cài đặt Keyset cursor vào trong ứng dụng. Sub cmdOpenRecordset_Click() Dim rsPublishers As Recordset Set rsPublishers = New Recordset With rsPublishers .Open "SELECT pub_id FROM Publishers", cnStateUBookstore, _ adOpenKeyset End With End Sub Chương 6 _Phần 2 _ Ðoạn 2 : Choosing Cursor Location Server Side Cursor : Có 2 phía mà cursor được cài đặt là phía Server và phía Client. Server side cursor là nơi tất nhiên mà ADO sẽ đặt cursor vào. Xử dụng Sever side cursor sẽ tiện lợi hơn là client side cursor vì ít gặp trở ngại về phương tiện tryuền thông (less network traffic). Ðể đặt Server side cursor vào trong ứng dụng bạn phải xác định CursorLocation của recordset Object là adUseServer. Sau đây là click event trình bày cho chúng ta thấy làm sao cài đặt Server-side cursor vào trong ứng dụng. Sub cmdOpenRecordset_Click() Dim rsStudents As Recordset Set rsStudents = New Recordset With rsStudents .CursorLocation = adUseServer .Open "SELECT StudentID FROM Students", cnStateUBookstore End With End Sub Client-side Cursors : Client-side cursors sẽ được tạo nên nếu các bạn hoán chuyển CursorLocation property của Recordset object thành adUseClient. Sau đó, các dử kiện trong recordset sẽ được cất giử ở phía client. Lợi ích của Client- Cursors là các bạn vẫn có thể làm việc với recordset mà không cần phải thông thương với Database Mainframe (Server). Ðiểm bất lợi là Client-cursors chỉ làm việc được với thể loại Static cursor type mà thôi. Và nếu dử kiện quá lớn (size of recordset) sẽ giới hạn rất nhiều trong việc cập nhật hóa tư liệu. Do đó, Client-side cursor chỉ thích hợp cho ứng dụng mà nó làm việc với số lượng nhỏ tư liệu mà thôi. Sau đây là click event trình bày làm sao để có cursors ở bên phía client. Sub cmdOpenRecordset_Click() Dim rsStudents As Recordset Set rsStudents = New Recordset With rsStudents .CursorLocation = adUseClient .Open "SELECT StudentID FROM Students", cnStateUBookstore End With End Sub Chương 6 _ Phần 3 : Enforcing Data Integrity Khi các bạn viết ứng dụng, các tư liệu phải được điều hành một cách hoàn chỉnh. Ứng dụng của bạn có thực tiển hay không đều lệ thuộc vào cách điều hành tư liệu. Từ chuyên nghiệp trong VisualBasic gọi là Data integrity. Và làm sao để điều hành và quản lý tốt tài liệu, chúng tôi sẽ lần lượt trình bày cùng các bạn 4 vấn đề sau đây : 1. Using Record Locking. Tàiliệu được khóa bằng cách nào ? 2. Using Database Transactions. Cách trao đổi dử kiện. 3. SQL Server Data Integrity Features. Những chuyện mà SQL Server có thể làm được để bảoquảntàiliệu một cách hoàn chỉnh. 4. Handling Referential Integrity Errors. Tránh trở ngại khi tiến hành ứng dụng. Chương 6 _ Phần 3 _ Ðoạn 1 : Using Record Locking Khi các bạn tạo thành một recordset (bản tài liệu), việc chọn lọc thể loại khóa (LockType) cho Data giúp cho ứng dụng của bạn có thể manage (điều hành) người xử dụng đi vào trong bản tàiliệu dể dàng hơn. Có nghỉa là không phải ai cũng có thể vào trong bản tàiliệu được và các bạn có thể giới hạn hoặc thêm quyền hành về cách xử dụng Data cho họ. Thí dụ như bạn có thể chắc chắn rằng không có 2 users thay đổi một chi tiết trong cùng một lúc. Sau đây là bản LockType property dùng để design cho dử kiện theo thể loại khóa nào, thích hợp cho ứng dụng. Locking Option Description adLockReadOnly Data chỉ có thể đọc mà thôi, không thể điều chỉnh. adLockPessimistic Data có thể điều chỉnh adLockOptimistic Data sẽ khóa lại khi có mệnh lệnh Update. adLockBatchOptimistic Thể loại này xử dụng ở Client side cursors và disconnected recordset. Ðây là thí dụ về cách làm sao đưa thể loại khóa vào trong recordset : Sub cmdOpenRecordset_Click() Dim cnStateUBookstore As Connection Dim rsStudents As Recordset Set cnStateUBookstore = New Connection With cnStateUBookstore .Provider = "SQLOLEDB" .ConnectionString = "User ID=sa;" & _ "Data Source=MSERIES1;" & _ "Initial Catalog=StateUBookstore" .Open End With Set rsStudents = New Recordset rsStudents.Open "SELECT StudentID FROM Students", _ cnStateUBookstore, adOpenKeyset, _ adLockPessimistic End Sub Chương 6_ Phần 3 _ Ðoạn 2 : Using database transaction Transaction là sự trao đổi dử kiện giửa 2 nơi trong hệ thống vi tính. Sự trao đổi này có tính cách quan trọng, cho nên VisualBasic đặt ra một luật là hoặc là trao đổi hoàn chỉnh, hoặc là không có thay đổi gì hết. Từ chuyên nghiệp gọi là “all or nothing” proposition. Khi tiến hành trao đổi dử kiện (transaction), nếu gặp trở ngại, thì VisualBasic sẽ giao trả trở lại dử kiện lúc ban đầu khi chưa có tiến trình transaction (gọi là roll back). Nếu tiến trình thành công thì dử kiện mới sẽ được cập nhật hóa (commit). Thí dụ như bạn xử dụng Autobank, bạn lấy tiền trong sổ của bạn, từng chuyện nạn làm như cho biết số bí mật, thể loại sổ bank, số tiền sẽ lấy .cho đến khi bạn lấy được tiền. Tiến trình transaction này gọi là commit. Nhưng nếu có trở ngại như Autobank đó không đủ tiền cung ứng theo nhu cầu của bạn thì nó sẽ giử nguyên số tiền trong sổ của bạn lúc chưa rút. Tiến trình transaction này gọi là roll back. Có 2 thể loại transactions là : implicit (tàng trử) và explicit (dứt khoát). Mời các bạn tiếp tục theo dỏi, chúng tôi sẽ trình bày thế nào là Implicit transaction và explicit transaction. Implicit transactions : Implicit transactions không cho phép các bạn tập trung các mệnh lệnh (commands) lại với nhau. Xử dụng Implicit transaction, các bạn không thể roll back hay commit một cách tự động. Implicit transaction cần phải thông báo có thay đổi trong bản tàiliệu (resubmit), thì tàiliệu mới cập nhật hóa được. Trong SQL server, implicit transaction sẽ được xử dụng một cách hiển nhiên Explicit transactions : Explicit transaction cho phép các bạn xử dụng multiple SQL statements. Tất cả các mệnh lệnh còn có thể tập trung lại trong một nhóm nữa. Có 3 methods là BeginTrans, RollbackTrans và CommitTrans. Khi BeginTrans tiến hành thì nó là một phần của transaction. Khi RollbackTrans hay CommitTrans tiến hành thì transaction sẽ được chấm dứt và mệnh lệnh sẽ sẳn sàng cho một transaction mới. Sau đây là thí dụ làm sao để cài đặt explicit transaction vào trong command Sub cmdMakeChanges_Click() Dim cnStateUBookstore As Connection Set cnStateUBookstore = New Connection With cnStateUBookstore .Provider = "SQLOLEDB" .ConnectionString = "User ID=sa;" & _ "Data Source=MSERIES1;" & _ "Initial Catalog=StateUBookstore" .Open End With ' A Transaction space is created cnStateUBookstore.BeginTrans ' Turn on the error handler On Error Goto Error_Handler ' SQL Commands are executed in the transaction cnStateUBookstore.Execute "INSERT INTO Authors ." cnStateUBookstore.Execute "DELETE FROM Publishers ." ' If all commands are successful, commit them cnStateUBookstore.CommitTrans Exit Sub Error_Handler: ' If an error occured, roll back the changes cnStateUBookstore.RollbackTrans MsgBox "An error occured changing the records.", vbExclamation End Sub Chương 6 _Phần 3 _Ðoạn 3 : SQL Server Data Integrity features SQL Server có thể làm một số việc giúp cho các bạn làm thế nào để quản lý tàiliệu sao cho hoàn chỉnh. Từ Visual Basic, ADO sẽ tự động nhận lấy những ưu điểm này từ SQL Server. Những ưu điểm đó, từ chuyên nghiệp trong tiếng Anh gọi là SQL Sever Data integrity features. Và tùy theo loại feature gì ? VisualBasic sẽ báo cho các bạn biết lý do vì sao mà xảy ra sự cố, khi ứng dụng gặp trở ngại về sự trục trặc trong lúc trao đổi tài liệu. Tiện lợi là ứng dụng vẫn làm việc và các bạn không cần phải khóa kho nhu liệu hay ứng dụng lại để điều chỉnh. Do đó, việc trao đổi thông tin giửa người chịu trách nhiệm về kho nhu liệu (Database administrator) và người viết ứng dụng như chúng ta rất quan trọng. Tại sao ? Vì chúng ta xác định thể loại tàiliệu nào dể dàng hơn và việc tìm kiếm hay giử gìn tàiliệu sẽ dể dàng hơn. SQL server có một số điều kiện buột chúng ta phải làm theo thì như vậy các features mà SQL Server làm được sẽ hoạt động hửu hiệu hơn. Referential Integrity Constraints : Ðể tránh sự cố khi trao đổi thông tin, SQL Server đặt ra một số điều kiện bắt buộc người viết ứng dụng phải tuân theo. Từ chuyên nghiệp gọi là constraints. Constraints liên quan đến việc design database (tạo kiểu mẩu cho bản tài liệu), chẳng hạn như thể loại của table, data type, data field .Sau đây là những vấn đề có liên quan đến constraints 1. Contrainst có quan hệ với field trong table .Thí dụ như field của Data là ngày tháng trong bản tàiliệu chẳng hạn thì khi bạn yêu cầu object trình bày chi tiết về ngày tháng, bạn phải chỉ rỏ ra field gì ? ở đâu trong bản tài liệu. 2. Contraints được dựng nên có thể xử dụng bởi SQL Server CREATE TABLE statement và liên hệ trực tiếp với cách tạo thành kiểu mẩu của table trong Database. 3. Contraints có thể xử dụng trong ứng dụng để việc trao đổi thông tin được hoàn chỉnh. Thí dụ như bạn muốn biết ngày, tháng (time) thì ứng dụng chỉ cung cấp tin tức cho các bạn về ngày tháng mà thôi Sau đây là 5 thể loại về Constraints, chúng tôi sẽ nói nhiều về vấn đề này ở phần tiếp theo 1. PRIMARY 2. UNIQUE 3. FOREIGN KEY 4. DEFAULT 5. CHECK Validation Rules : Chúng ta có thể hiểu validation rules ở đây là những luật lệ giúp cho việc trao đổi thông tin giửa client và server được hoàn chỉnh. Những luật lệ này bổ túc cho constraints, như đã nói ở trên. Thông thường, rule được xét trong những trường hợp như sau : • A set of values, một nhóm tàiliệu trong Database, thí dụ như chi tiết cá nhân của học sinh. • A range of values, số lượng tàiliệu trong Database, thí dụ như bao nhiêu học sinh trong khóa. • A format, chi tiết của field như text, time, currency . Field Defaults là một trong những constraint trong cách điều hành thông tin sao cho hoàn chỉnh. Trong SQL Server Database, mỗi field trong table đều phải chứa đựng một chi tiết và bạn vẫn có thể bỏ trống. Trong trường hợp người xử dụng bỏ xót một chi tiết nào đó, thì các bạn xử dụng field defaults điền chi tiết vào khoản trống đó. Còn điền bằng cách nào thì xin mời các bạn tham khảo SQL Server Database .Nếu có dịp chúng tôi sẽ trình bày cùng các bạn sau khi chấm dứt bài học về Visual Basic. Chương 6 _Phần 3 _Ðoạn 4 : Handling referential integrity errors Referential integrity là những sự cố có thể xảy ra trong lúc người xử dụng làm việc với Data trong Database. Thí dụ như trong Database có 2 bản table là Customers và Orders. Vì quan hệ giửa 2 tables (từ chuyên nghiệp gọi là relationship) cho nên khi bạn xóa bỏ đi một chi tiết nào đó một trong 2 table thì những chi tiết còn lại trong table kia sẽ có sự cố. Và sự cố kỷ thuật này gọi là referential integrity violation Nếu referential integrity violation xảy ra, ứng dụng sẽ nhận run time error và tùy theo thể loại error gì, ứng dụng sẽ báo cáo tình trạng violation (Data bị xâm phạm). Như chúng tôi có nói ở phần trên, có 3 điều luật về giá trị của Data là set of value, range of value, format, nếu các bạn cẩ thận trong việc xếp đặt điều luật thì các bạn có thể hạn chế được run time error. VisualBasic có thể ngừa cho các bạn tránh được sự cố gây ra bởi Data bị xâm phạm (trapping for referential integrity violation). Mời các bạn xem click event trình bày khi có sự cố xảy ra thì ứng dụng sẽ tiến hành như thế nào Sub cmdDeleteRecords_Click() Dim cnStateUBookstore As Connection Dim errStateU As Errors Set cnStateUBookstore = New Connection With cnStateUBookstore .Provider = "SQLOLEDB" .ConnectionString = "User ID=sa;" & _ "Data Source=MSERIES1;" & _ "Initial Catalog=StateUBookstore" .Open End With On Error Goto Error_Handler: cnStateUBookstore.BeginTrans ' this command will generate a foreign key violation error cnStateUBookstore.Execute "DELETE FROM Books WHERE BookID = 14" cnStateUBookstore.CommitTrans Exit Sub Error_Handler: ' trap for the foreign key violation from SQL Server using the ' OLE DB Provider for SQL Server. If errStateU.Number = -2147217900 Then ' the transaction will be rolled back cnStateUBookstore.RollbackTrans End If End Sub . dụng, một số tài liệu nhất định sẽ được xử dụng thường xuyên dựa trên SQL query statement. Số tài liệu này gọi là nhóm tài liệu. Nhóm tài liệu được xử. hóa các thay đổi về tài liệu khi có người xử dụng thay đổi chi tiết trong bản tài liệu. Theo thứ tự, thì các chi tiết trong bản tài liệu sẽ được cập nhật