I. File Global.asa
1. Giới thiệu đối tợng ADO
1.1. Khái niệm ADO (Activẽ Data Object)
ActiveX Data Object là lớp đối tợng COM (Compenent Object Model) tập trung vào xử lý dữ liệu thông qua OLEDB của Windows. ADO thiết kế cho mục đích truy xuất dữ liệu tổng quát không chỉ dùng để truy xuất dữ liệu thuần tuý mà còn xử lý đợc cả dữ liệu file hay bất kỳ loại dữ liệu nào có hỗ trợ cơ chế cho phép giao tiếp thông qua OLEDB
Mô hình kiến trúc của ADO tơng tác giữa ứng dụng và nguồn dữ liệu
Trong đó, OLE-DB (Object Linking and Embedding - Database) – liên kết và nhúng đối tợng, cho phép ngời dùng truy xuất mọi loại dữ liệu nh CSDL, bảng biểu, đồ thị, th điện tử...
Application
VC++ VB Script Java
ADO
OLEDB
Data Store
1.2. Trình tiêu thụ (consumer) và trình cung cấp (provider)
Trong bớc lập trình, chơng trình viết ra chính là trình tiêu thụ dữ liệu bởi nó cần truy xuất vào các nguồn dữ liệu để xử lý. Còn trình cung cấp là tập lệnh cho phép truy xuất vào nguồn dữ liệu theo cách đặc trng của chúng. Provider cho phép giao tiếp giữa nguồn dữ liệu và tầng điều khiển OLEDB. Và ADO chỉ trao đổi với nguồn dữ liệu thông qua OLEDB mà không cần quan tâm tới cách thức làm việc của Provider. Để giúp OLEDB biết đợc Provider nào cần phải giao tiếp, khi mở kết nối ADO cần chỉ định trình cung cấp dữ liệu Provider tơng ứng. Microsoft cung cấp sẵn một số Provider cho phép truy xuất dễ dàng vào các nguồn dữ liệu đang thông dụng nh:
Jet OLEDB 4.0 – Cơ sở dữ liệu Access
DTS Packages – Dịch vụ chuyển đổi dữ liệu trong SQL Server ODBC Driver – Provider ch phép truy xuất nguồn dữ liệu thông qua ODBC
SQL Server – Cơ sở dữ liệu SQL Server Oracle – Cơ sở dữ liệu Oracle
Simple Provider – Cơ sở dữ liệu dạng Text
Để tơng tác với CSDL, chúng ta sử dụng đối tợng ADO. ADO là công nghệ của hãng Microsoft tự động cài đặt khi cài đặt Windows có cài đặt IIS. ADO là chơng trình giao tiếp để truy cập dữ liệu trong CSDL.
Khi kết nối CSDL từ trang ASP, ta có thể thao tác theo các bớc sau
- Khởi tạo đối tợng Connection.
- Mở kết nối CSDL với chuỗi kết nối.
- Khởi tạo đối tợng RecordSet.
- Xử lý dữ liệu trong đối tợng RecordSet.
- Đóng đối tợng RecordSet.
- Đóng đối tợng Connection.
- Giải phóng hai đối tợng RecordSet và Connection. 2. Mô hình đối tợng ADO
Có ba đối tợng chính trong mô hình đối tợng ADO
o Đối tợng Connection o Đối tợng Command
o Đối tợng RecordSet
Trong phần này chúng ta sẽ tìm hiểu chi tiết hai đối tợng RecordSet và Connection là hai đối tợng chính dùng để kết nối và xử lý dữ liệu SQL Server, Access và một số cơ sở dữ liệu khác từ trong trang ASP.
2.1. Đối tợng kết nối (Connection)
Cho phép thực hiện việc mở kết nối đến nguồn dữ liệu cần truy xuất. Thông qua Connection chỉ cần chỉ định trình cung cấp OLEDB Provider sẽ dùng để tiếp cận dữ liệu. Các thông tin kết nối bổ sung khác nh username, password, server name,.. thờng đợc lu vào một chuỗi gọi là chuỗi kết nối (Connection String).
* Khai báo đối tợng Connection
Chú ý rằng mọi biến khai báo trong ASP đều có kiểu dữ liệ Variant, điều này có nghĩa là ta không thể dùng từ khoá As nh trong VB.
Để khai báo đối tợng Connecction, ta sử dụng cú pháp nh sau:
Dim myCon
* Khởi tạo đối tợng
Sau khi khai báo biến myCon với kiểu dữ liệu là Variant, ta có thể khởi tạo đối tợng này bằng phơng thức CreateObject của đối t- ợng Server nh đã trình bày với cú pháp nh sau
Set
myCon=CreateObject("ADODB.Connection")
Nếu sử dụng hệ điều hành Windows 9x với trình chủ Web là Personal Web Server, khai báo trên có thể đợc viết lại nh sau:
Set
myCon=Server.CreateObject("ADODB.Connect ion")
* Mở kết nối với CSDL
Sau khi khởi tạo đối tợng Connection, để tơng tác với CSDL ta phải kết nối với CSDL với cú pháp nh sau:
myCon.Open “Chuỗi kết nối”
Tuỳ thuộc vào loại CSDL cần tơng tác mà ta sử dụng trình điều khiển tơng ứng.
- Mở kết nối CSDL Access: Khi mở kết nối CSDL Access, ta sử dụng chuỗi kết nối với các thuộc tính nh sau:
strCon="Provider= Microsoft.Jet.OLEDB.4.0";&_ "Data
Source=D:\LTWeb\Database\BTTN.mdb" myCon.Open strCon
Chú ý, ta có thể sử dụng phơng thức ServerVariables của đối t- ợng Request để lấy đờng dẫn vật lý của tập tin nh khai báo sau:
strPath=request.ServerVariables("APPL_PHYSICAL_P ATH")
strCon="Provider=" & _
"Data Source= " & strPath & _ "\BTTN\BTTN.mdb"
myCon.Open strCon
Ví dụ 2.1. Kết nối với cở sở dữ liệu Access. <HTML>
<head>
<title> Welcome to ADO and ASP 3.0 </title> </head>
<body>
<h4> Welcome to ADO and Access </h4> <% Dim myCon,strCon strCon="Provider=Microsoft.Jet.OLEDB.4.0;" &_ "Data Source=D:\LTWeb\database\bttncd.mdb" Set myCon=CreateObject("ADODB.Connection") myCon.Open strCon if myCon.State=1 then
Response.Write "Connected to Access" else
Response.Write "Connect fail" end if
myCon.Close
Set myCon=Nothing %>
<hr size=1 color=red> </body>
Hoặc ta có thể viết nh sau <HTML>
<head>
<title> Welcome to ADO and ASP 3.0 </title> </head>
<body>
<h4> Welcome to ADO and Access </h4> <%
Dim myCon,strCon
strPath=request.ServerVariables("APPL_PHYSICAL_PATH" )
strCon="Provider=Microsoft.Jet.OLEDB.4.0;" &_ "Data Source= "& strPath
&"\DATABASE\BTTNCD.mdb"
Set myCon=CreateObject("ADODB.Connection") myCon.Open strCon
if myCon.State=1 then
Response.Write "Connected to Access" else
Response.Write "Connect fail" end if
myCon.Close
Set myCon=Nothing %>
</body> </html>
- Mở kết nối với CSDL SQL Server: nếu ta sử dụng đặc quyền SQL Server để đăng nhập CSDL SQL Server, ta sử dụng chuỗi kết nối nh sau: strCon="DRIVER=SQL Server;UID=sa;PWD=sa;"Database=Northwind;Server=." myCon.Open strCon hoặc: strCon="Provider=SQLOLEDB.1;" & _
"Persist Security Info=False;UID=sa;" & _ "PWD=sa;Initial Catalog= Northwind;Server=." myCon.Open strCon
* Thực thi phát biểu SQL
Sau khi mở kết nối CSDL với chuỗi kết nối khai báo trong phần trên, bằng cách sử dụng phơng thức Execute của đối tợng Connection ta có thể thực thi phát biểu SQL dạng hành động hoặc một thủ tục nội tại với cú pháp nh sau:
myCon.Execute “SQL Statement”
Ví dụ 2.2. Thực hiện câu lệnh SQL sử dụng phát biểu Create table để tạo bảng:
<html> <head>
<title> Welcome to ADO and ASP 3.0 </title> </head>
<body>
<h4>Execute SQL Statement</h4>
<%
strPath=request.ServerVariables("APPL_PHYSICAL_PATH" )
strCon="Provider=Microsoft.Jet.OLEDB.4.0;" &_
"Data Source= "& strPath &"\DATABASE\BTTNCD.mdb"
Set myCon=CreateObject("ADODB.Connection") myCon.Open strCon
if myCon.State=1 then
strSQL="Create Table tblABCDE"
strSQL=strSQL & "(AD int, DD int)" myCon.Execute strSQL
Response.Write "Created Table" else Response.Write "Fail" end if myCon.Close Set myCon=Nothing %>
<hr size=1 color=red> </body>
* Đóng kết nối
Sau khi mở kết nối CSDL và thực thi các câu lệnh SQL, hay mở tập dữ liệu, nếu không có nhu cầu sử dụng đối tợng Connection, ta có thể đóng kết nối tránh trờng hợp có nhiều kết nối đang mở bằng phơng thức close, với cú pháp nh sau:
myCon.Close
* Giải phóng đối tợng:
Nếu không có nhu cầu sử dụng đối tợng Connection, ta nên sử dụng phát biểu Set để huỷ đối tợng này và giải phóng bộ nhớ đã cấp phát cho chúng với cú pháp nh sau:
Set myCon=Nothing
Chú ý:
- Nếu ngay sau đó ta sử dụng lại đối tợng này, cần phải khởi tạo trở lại bằng phơng thức CreateObject của đối tợng Server.
- Nếu trớc đó cha khai báo đóng kết nối bằng phơng thức Close, thì phát biểu Set để huỷ bỏ đối tợng Connection sẽ tự động đóng trớc khi bị huỷ.
Có thể kết nối và truy xuất vào nguồn dữ liệu mà không bắt buộc phải dùng đối tợng Connection. Các đối tợng khác nh Command, RecordSet, Record,.. cũng cho phép mở trực tiếp kết nối. Tuy
nhiên sử dụng đối tợng Connection sẽ cho phép ta tách biệt thao tác kết nối và thao tác truy cập cơ sở dữ liệu. Hơn nữa đối tợng Connection còn cung cấp thêm một số chức năng chuyên dụng khác nh cho phép thực thi câu lệnh SQL tác động vào dữ liệu nh Insert, Update, Delete, gọi thủ tục Procedure Store,.. hoặc kiểm soát giao tác transaction nh Rollback, commit.
2.2. Đối tợng RecordSet
Là đối tợng sử dụng thờng xuyên trong ADO. Cung cấp kết quả trả về từ câu lệnh truy vấn một tập các mẩu tin. Trang ASP có thể dùng vòng lặp để duyệt qua các mẩu tin này và hiển thị dữ liệu kết xuất ra trang Web phía trình duyệt. Ngoài ra RecordSet còn cho phép thực hiện lọc dữ liệu từ tập các mẩu tin, truy xuất đến từng trờng cụ thể của mẩu tin thông qua đối tợng Field hoặc danh sách các tr- ờng trong mẩu tin thông qua đối tợng Fields.
* Khai báo đối tợng
Tơng tự nh đối tợng Connection, khi có nhu cầu lấy dữ liệu là một giá trị hay một mẫu tin, ta sử dụng phát biểu để khai báo đối tợng RecordSet với cú pháp:
Dim myRs
* Khởi tạo đối tợng
Sau khi khai báo, ta có thể khởi tạo đối tợng này bằng phát biểu Set và phơng thức CreateObject của đối tợng Server nh sau
Set myRst=CreateObject("ADODB.RecordSet")
hay Set
myRst=Server.CreateObject("ADODB.RecordSet")
* Mở tập dữ liệu
Để mở tập điều khiển ứng với phát biểu SQL dạng Select, Table, View, Query hay thủ tục nội tại của SQL Server có giá trị trả về, ta sử dụng phơng thức Open với khai báo nh sau:
myRst.Open "Phát biểu SQL", myCon, CursorType, LockType
Trong đó
• myCon là đối tợng kết nối đã mở ứng với CSDL nào đó.
• Hai tham số tuỳ chọn CursorType (mặc định adOpenForwardOnly), LockType (mặc định là adLockReadOnly) ứng với kiểu con trỏ và loại khoá dữ liệu. - Giá trị của CursorType
• adOpenDynamic (tơng đơng với hằng số 2): Khi khai báo hằng số này, ứng với con trỏ (cursor) động, ngời sử dụng khác có thể thay đổi, xoá và di chuyển trên mẫu tin mà ta đang mở ngoại trừ bookmark.
• adOpenForwardOnly (tơng đơng hằng số 0) đây là giá trị mặc định, khi khai báo hằng số này, con trỏ chỉ di chuyển một chiều. Đối với trờng hợp mở tập dữ liệu mà không điều hớng (navigation) trên mẩu tin, ta nên sử dụng tuỳ chọn với giá trị này.
• adOpenKeyset (tơng đơng hằng số 1): Tơng tự nh adOpenDynamic nhng không cho phép ngời sử dụng khác thêm hay xoá hoặc sửa mẩu tin.
• adOpenStatic (tơng đơng với hằng số 3): Đây là dạng con trỏ tĩnh, nghiêm cấm thay đổi, xoá mẩu tin từ ngời sử dụng khác. - Giá trị của LockType
• adLockBatchOptimistic (tơng đơng với hằng số 4): Yêu cầu cập nhật tập dữ liệu theo đó.
• adLockOptimistic (tơng đơng với hằng số 3): Không cho phép cập nhật mẩu tin khi gọi phơng thức Update.
• adLockReadOnly (tơng đơng với hằng số 1): Chỉ cho phép đọc.
Chẳng hạn, đối tợng với trờng hợp này chúng ta tìm hiểu ví dụ sử dụng đối tợng RecordSet để mở bảng dữ liệu giaovien nh sau:
Ví dụ 2.3. Mở bảng dữ liệu. <html>
<head>
<title> Welcome to ADO and ASP 3.0 </title>
</head> <body> <h4>RecordSet</h4> <% Dim myCon,strCon strPath=request.ServerVariables("APPL_PHYSICAL_PATH" ) strCon="Provider=Microsoft.Jet.OLEDB.4.0;" &_ "Data Source= "& strPath
&"\DATABASE\BTTNCD.mdb"
Set myCon=CreateObject("ADODB.Connection") Set myRst=CreateObject("ADODB.RecordSet") myCon.Open strCon
if myCon.State=1 then
Response.Write "Ket noi duoc : " else
Response.Write "Khong ket noi duoc.." end if
strSQL="Select * from giaovien" myRst.Open strSQL , myCon
Response.Write "Existing records" else
Response.Write "Record not found" end if myRst.Close myCon.Close Set myRst=Nothing Set myCon=Nothing %>
<hr size=1 color=red> </body>
</html>
* Xử lý dữ liệu
Sau khi mở tập mẩu tin với các tuỳ chọn trên, tuỳ thuộc vào loại cursor mà ta có thể thêm, xoá, cập nhật hay di chuyển trên từng mẩu tin.
Đối tợng RecordSet cung cấp các phơng thức và thuộc tính cho phép duyệt hay xử lý dữ liệu trong tập dữ liệu đang nắm giữ bởi đối tợng này.
• EOF: trả về giá True nếu cursor đang nằm sau mẩu tin cuối cùng. Trong trờng hợp đối tợng RecordSet không nắm giữ mẩu tin nào, thuộc tính này có giá trị là True, ngợc lại có giá trị là False.
Ví dụ, ta kiểm tra mẩu tin trong đối tợng RecordSet có tồn tại hay không nh sau:
if Not myRst.EOF then Tồn tại
else
Không tồn tại end if
• BOF: Trả về giá trị True nếu cursor đang nằm trên mẩu tin đầu tiên. Trong trờng hợp đối tợng RecordSet không nắm giữ mẩu tin nào, thuộc tính này sẽ có giá trị là True, ngợc lại có giá trị là False.
Ví dụ, ta kiểm tra mẩu tin trong đối tợng RecordSet có tồn tại hay không nh sau:
if myRst.BOF then Tồn tại
else
Không tồn tại end if
• Fields("Fieldname"): Gán hay lấy giá trị của cột trong bảng dữ liệu.
Ví dụ: myRst.Fields("MaGV")="NHA"
• RecordCount: Trả về giá trị là tổng số mẩu tin đang có trong đối tợng RecordSet với loại cursor động.
Ví dụ, ta lấy số mẩu tin trong đối tợng RecordSet nh sau
Dim i
i=myRst.RecordCount
• MoveLast: Di chuyển cursor đến mẩu tin cuối cùng.
• MoveNext: Di chuyển cursor đến mẩu tin kế tiếp.
• MovePrevious: Di chuyển cursor đến mẩu tin trớc đó.
Ví dụ: Duyệt qua các mẫu tin và truy xuất vào các trờng cuả mẫu tin
Do While not rs.eof
Rs [.fields](“field_name”) rs.movenext
loop
rs.close
Các cách truy cập hợp lệ và tơng đơng: Rs(“field_name”)
Rs.fields(“field_name”)
Rs.fields(“field_name”).value Rs(1).value
Rs.fields(1).Value
Nếu muốn duyệt qua tất cả các trờng trong mẩu tin ta có thể dùng lệnh:
For each Fld in rs.fields
Response.write fld.name + “:” + fld.value + “<br>”
Next
Có thể lọc qua các mẫu tin trong RecordSet
Có thể sử dụng mệnh đề Where của câu lệnh Select hoặc có thể sử dụng thuộc tính Filter của RecordSet để chỉ định điều kiện lọc sau khi đã trích xuất dữ liệu. Ví dụ:
sqlStr=”Select * from Products” rs.open sqlStr,conn
rs.filter= “ productCode=’” & SpecialCode & “’”
Thuộc tính Filter cho phép sử dụng mệnh đề lọc gần giống với mệnh đề Where
• PageSize: Thuộc tính này cho phép gán hay đọc số mẩu tin trình bày trên một trang. điều này có nghĩa là khi ta có nhiều mẩu tin muốn trình bày, bằng cách sử dụng thuộc tính này để yêu cầu kết xuất số mẩu tin chỉ định, ví dụ 10 mẩu tin/1trang.
• PageCount: Thuộc tính này trả về số trang đợc tính dựa trên thuộc tính PageSize, chẳng hạn tổng số mẩu tin có trong đối t- ợng RecordSet là 153 mẩu tin, nếu ta khai báo thuộc tính PageSize là 15 (15 mẩu tin/1trang), khi đó thuộc tính PageCount sẽ tả về 11 trang.
Có thể phân trang với đối t ợng RecordSet
Đối tợng RecordSet cung cấp 3 thuộc tính quan trọng sau để sử dụng phân trang:
PageSize: Kích thớc mẩu tin trong một trang
PageCount: Tổng số trang RecordSet truy vấn đợc
AbsolutePage: Chỉ định trang hiện hành đang cần đợc đọc Để RecordSet có khả năng phân trang, cần thiết lập thêm tham số cho RecordSet trớc khi thực hiện truy vấn:
Rs.CursorLocation=3 ‘ Có thể sử dụng hằng adUseClient
Rs.PageSize=15 ‘ 15 bản ghi trong một trang Tiếp theo mở đối tợng RecordSet truy vấn dữ liệu với tuỳ chọn là các hằng adOpenForwardOnly(0), adLockReadOnly (1) truy vấn cho phơng thức Open nh sau:
Rs.open sqlStr, Conn, 0,1
Công việc sau cùng là định vị trang thông qua thuộc tính AbsolutePage. Ta lu lại vị trí hiện hành của trang dữ liệu
thông qua giá trị chứa trong thẻ <input hidden>. Giá trị này sẽ đợc chuyển về trình chủ mỗi khi ngời dùng kích vào.
Xét ví dụ sau:
<%sqlStr="SELECT * FROM Products " ' page navigate session here ...
Dim lCurrentPage Dim lPageCount lCurrentPage = CLng(Request("page")) If lCurrentPage < 1 Then lCurrentPage = 1 End If rs.CursorLocation = 3 rs.PageSize = 15
rs.Open sqlStr, conn, 0, 1 'Const
adOpenForwardOnly=0,adLockReadOnly = 1 lPageCount = rs.PageCount
If lCurrentPage > lPageCount Then lCurrentPage = lPageCount
End If
if not rs.eof then
rs.AbsolutePage = lCurrentPage end if
call
ShowPageNavigation(lCurrentPage,lPageCount)
Do While rs.AbsolutePage = lCurrentPage And Not rs.Eof
Response.write rs("ProductName")
rs.movenext loop
%>
<form name="viewFrm">
<input type=hidden name=page> </form>
<%
Sub ShowPageNavigation (lCurrentPage,lPageCount) If lCurrentPage <> 1 AND lCurrentPage <> 0 Then
%>
<A HREF="javascript:setValue('<%= lCurrentPage - 1 %>');">Previous
<% Else %> Previous
<% End If%>
<A HREF="javascript:setValue('<%= lCurrentPage + 1%>');">Next
<% Else %> Next
<% End If%><BR>Page<B><%= lCurrentPage%></B> <%= lPageCount%>
<%End Sub %>
<script language=javascript> function setValue(page){
viewFrm.page.value= page; viewFrm.submit();
}
</script>
• CursorLocation: Là loại cursor (mặc định là adUseServer) áp dụng cho đối tợng RecordSet khi mở tập tin, nếu giá trị gán là adUseClient, cursor thực hiện phía trình khách.
• AddNew: Thêm mẩu tin mới vào bảng dữ liệu quản lý bởi phơng thức RecordSet.
• Update: Cập nhật mẩu tin vào dữ liệu nguồn. Ví dụ
sqlStr=”Select * From Accounts” rs.open sqlStr,Conn
‘ Thêm tài khoản mới vào bảng Accounts
rs.Addnew
‘gán giá trị cho mẩu tin
with rs
.fields(“username”)= ‘New User’ .fields(“password”)=’***’
end with