TAHA
10-28-2009, 10:25 PM
ارتباط ASP با بانك های اطلاعاتی از طريق واسطی بنام ADO انجام می گيرد. با استفاده از رابط فوق می توان به انواع داده های ذخيره شده بسادگی، در كمترين زمان و صرفا بكمك يك مسير دستيابی پيدا كرد. به همين دليل می توان ادعا كرد كه ADO ساده ترين روشی است كه تاكنون برای ذخيره و بازيابی داده ها بوجود آمده است.ADO نسخه 5 / 2 دارای پنج شئ اساسی با نام : Connection , Command, RecordSet , Record , Stream است. دو شی Record و Stream در نسخه قبلی ADO وجود نداشتند. در اين مقاله به بررسی برخی از اشياء عمده ADO و متدهای مربوطه آنها خواهيم پرداخت.
شئ Connection
قبل از هر گونه ذخيره و بازيابی داده ها از بانك اطلاعاتی می بايست با ايجاد و مقدار دهی اوليه يك Connection زمينه لازم جهت ارتباط با بانك اطلاعاتی را بوجود آورد. در ADO با استفاده از شی Connection يك ارتباط با بانك اطلاعاتی ايجاد و پس از انجام عمليات دلخواه در رابطه با بانك اطلاعاتی و در زمانيكه به وجود آن ديگر نياز نباشد، می توان آن را حذف كرد. Open كردن يك ارتباط به بانك اطلاعاتی پروژه ای واحد با نام ( ADODB(ActiveX Data Objects Database بوده كه خود شامل تمامی اشياء ADO است. برای ايجاد يك Connection نظير ساير اشياء ASP از متد Server.CreateObject استفاده می گردد.
Dim Conn
Set Conn = Server.CreateObject("ADODB.Connection")
بصورت پيش فرض Connection فقط خواندنی می باشند، شما می توانيد وضعيت فوق را تغيير داده و در صورت نياز و بكمك صفات مربوط به شی فوق ارتباطاتی از نوع خواندنی / نوشتنی و يا فقط نوشتنی ايجاد نمائيد. در زمان استفاده از ADO می توان از مجموعه ای ثوابت كه دربردارنده مقادير متفاوتی برای آيتم های متفاوت می باشند و پيشاپيش تعريف شده اند استفاده كرد. اين ثوابت در فايلی با نام Adovbs.inc قرار دارند. بمنظور استفاده از ثوابت فوق در صفحات ASP خود، می بايست فايل فوق را بكمك دستور Include به برنامه های خود ملحق نمائيم.
<!-- #INCLUDE FILE="adovbs.inc" -->
اگر فايل adovbs.inc را توسط اديتوری نظير Notepad فعال نمائيد، ثوابت تعريف شده را بصورت مجموعه ای از گروهها مشاهده خواهيد كرد. پس از ايجاد يك Connection با بانك اطلاعاتی می توان نوع ( Mode ) ارتباط را بكمك استفاده از ثوابت تعريف شده مشخص نمود. در صورتيكه بخواهيم از بانك اطلاعاتی صرفا اطلاعاتی را بخوانيم از ثابت adModeRead ، فقط اطلاعاتی را در بانك اطلاعاتی بنويسيم از ثابت adoModeWrite و در نهايت در صورتيكه قصد داريم بطور همزمان اطلاعاتی را از بانك اطلاعاتی خوانده و در آن اطلاعات جديدی را نيز بنويسيم از ثابت adoModeReadWrite استفاده می گردد. توصيه می گردد با توجه به نوع رفتاری كه با بانك اطلاعاتی خواهيم داشت آن را باز نمائيم چراكه در صورتيكه صرفا قصد خواندن و يا نوشتن را در يك بانك اطلاعاتی داشته باشيم و نخواهيم دو عمليات را با هم انجام دهيم، باز كردن بانك اطلاعاتی بصورت هم خواندنی و هم نوشتنی ( adoModeReadWrite ) سرعت دستيابی به بانك اطلاعاتی را كاهش خواهد داد.
ConnectionString
پس از تعيين Mode، می بايست صفت Connectionstring مربوط به شی Connection را مقدار دهی مناسب نمود. صفت فوق دارای چندين بخش بوده كه می بايست مشخص گردند: نام Provider، نام سرويس دهنده بانك اطلاعاتی، نام بانك اطلاعاتی كه قصد استفاده از آن را داريد، User Id لازم جهت اتصال به بانك اطلاعاتی (UID)، رمز عبور برای كاربرخاص ( PWD ).
هر يك از بخش های فوق توسط علامت ";" از هم جدا می شوند. مثلا در ساده ترين حالت می توانيد از يك Data Source Name يا DSN يا مربوط به ODBC، يك User ID، و يك رمز عبور جهت اتصال به بانك اطلاعاتی استفاده نمائيد. يك DSN خود شامل نام Provider، نام سرويس دهنده بانك اطلاعاتی و نام بانك اطلاعاتی بوده و ديگر نيازی به مشخص نمودن مجدد آنها نخواهد بود. به مثال زير توجه فرمائيد.
Dim Conn
Set Conn = Server.Create0bject("ADODB.Connection")
Conn.Mode = adModeReadWrite
Conn.ConnectionString = "DSN=myDSN;UID=Javad;PWD=7474;"
روش فوق بهترين حالت ايجاد يك ارتباط نيست زيرا DSN بصورت پيش فرض از MSDASQL Provider استفاده می كند. اما JET OLEDB Provider بمراتب سريعتر و قابليت های بيشتری را دارا است. بنابراين می توان جهت ارتباط با بانك اطلاعاتی مطابق زير عمل نمود:
Dim Conn, ConnStr
ConnStr= "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" + Server.MapPath(Path2DB)
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Mode = adModeReadWrite
Conn.ConnectionString = ConnStr
ConnectionString شامل نام Provider، نام سرويس دهنده بانك اطلاعاتی و نام بانك اطلاعاتی است. در مثال فوق از تابع Server.MapPath برای ترجمه مسير مجازی به مسير واقعی استفاده شده است. مثلا يك بانك اطلاعاتی موجود درwww.Test.com/test.mdb (http://pnu-club.com/redirector.php?url=http%3A%2F%2Fwww.test.com%2Ftes t.mdb) می تواند بصورت واقعی در مسير E:\web\Mydatabase\Test.mdb قرار گرفته باشد. تابع Server.MapPath آدرس نوع اول را به آدرس نوع دوم ترجمه خواهد كرد. توجه داشته باشيم كه شی ADODB.Connection نيازمند آگاهی از مسير واقعی بانك اطلاعاتی است. فراموش نكنيم كه قبل از باز نمودن Connection، تمامی تغييرات لازم بر روی صفت های مربوطه اعمال گردد. در صورتيكه بخواهيم پس از ايجاد ارتباط با بانك اطلاعاتی يك يا چند صفت مرتبط را تغيير دهيم، می بايست در ابتدا ارتباط خود را با بانك اطلا عاتی قطع (Connection، بسته گردد) و در ادامه تغييرات لازم را از طريق صفات مربوطه اعمال و مجددا Connection را برقرار نمود.
بمنظور باز نمودن يك Connection از متد Open مربوط به شئ Connection استفاده می گردد.
متد Connection.Open
در صورتيكه متد فوق بدون خطا اجرا گردد، يك ارتباط كاری ( عملياتی) با بانك اطلاعاتی ايجاد شده است.
متد Connection.Execute
برای بازيابی داده ها از يك بانك اطلاعاتی توسط ADO سه روش عمده وجود دارد. تمامی آنها در مرحله اول نياز به ارتباط با بانك اطلاعاتی خواهند داشت. ساده ترين حالت استفاده از متد Execute مربوط به شی Connection است. متد فوق سه پارامتر را خواهد داشت:- يك دستور SQL، يا Query، Table، View يا نام يك Stored Procedure كه توسط پارامتر CommandText مشخص خواهد شد.
• يك متغير با نام RecordsAffected، كه شامل تعداد ركوردهائی خواهد بود كه با توجه به Query اجرا شده توسط متد Execute مشخص می شود.
• يك ثابت اختياری با نام CommandTypeEnum كه به بانك اطلاعاتی خواهد گفت چه نوع عبارت و يا Query را می خواهيد اجرا نمائيد و اينكه يك شی Recordset را برگرداند يا خير.
پس از اجرای متد Execute ( به هر روش ممكن )، ركوردهای برگردانده شده در شئ RecordSet برگردانده خواهند شد. در صورتيكه از دستور SELECT استفاده شود ركوردهای برگردانده شده در شی RecordSet قرار خواهند گرفت. اما زمانيكه از دستورات INSERT و يا UPDATE استفاده گردد رکوردی باز گردانده نخواهد شد.
شئ RecordSet
از شی RecordSet جهت نگهداری رکوردها يا جدول دريافتی استفاده می گردد. اين شئ نظير يك جدول بانك اطلاعاتی دارای سطرها و ستون هائی است. در حقيقت شئ فوق يك تصور مجازی از يك جدول خواهد داد و بصورت فيزيكی يك جدول نيست. چراكه مقادير مورد نظری كه در ستون های اين شئ قرار می گيرد ممكن است حاصل تركيب (Join) چندين جدول ديگر باشند.
متد RecordSet.Open
در صورتيكه در هنگام استفاده از شئ RecordSet به هر نوع Cursor ( اشاره گری به هر يك از سطرهای موجود در جدول ) نياز داشته باشيد ( صرفا نه يك Cursor كه بصورت Forward-Only و يا Read-Only باشد ) می بايست به جای استفاده از متد Execute مربوط به شی Connection، مستقيما بانك اطلاعاتی را باز کنيد. شئ RecordSet نيز دارای متدی با نام Open است كه چندين پارامتر را بعنوان پارامتر اخذ می كند.
Recordset.Open CommandText, Connection|ConnectionString, Cursor-Type, LockType, Options
CommandText شامل SQL query بوده، Connection|ConnectionString شامل يك رجوع به شئ Connection باز شده و يا يك پارامتر معتبر Connectionstring است. پارامتر CursorType مقدار خود را از ثابتی با نام adCursorTypeEnm مطابق زير اخذ خواهد كرد:
• adopenForwardOnly: يك Cursor كه فقط امكان حركت بسمت جلو را دارد، برمی گرداند. ( پيش فرض). اگر نوع Cursor را مشخص ننمائيد، ADO همواره Cursor از اين نوع را بر می گرداند. همانگونه كه از نام آن مشخص است، صرفا می توان بسمت جلو در شئ RecordSet حركت نمود.
• AdOpenKeyset: يك Cursor از نوع Keyset را برمی گرداند. در چنين حالتی می توان جهت و نوع حركت را به هر نوع دلخواه انتخاب نمود (اولين ركورد، آخرين ركورد، بسمت جلو، بسمت عقب...). سرويس دهنده برای هر يك از سطرهای موجود در شئ RecordSet پس از اجرای Query يك Bookmark، ايجاد می كند. اين Bookmark ها تا زمانيكه شئ Recordset حيات دارد تغيير نخواهند كرد بنابراين در صورتی كه يك ركورد جديد توسط كاربر ديگری در بانك اطلاعاتی در آن زمان درج گردد، آن رکورد جديد برای ما قابل رؤيت نخواهد بود.
• adOpenDynamic: يك Cursor پويا را برمی گرداند. اين نوع Cursor مشابه Keyset است با اين تفاوت كه امكان مشاهده ركوردهای جديد نيز وجود خواهد داشت. يك Cursor پويا بصورت پيوسته ركوردهای جديد و يا تغيير يافته را بررسی و حاصل را در شی RecordSet بصورت پويا منعكس خواهد كرد.
• adOpenStatic: يك Cursor ايستا بهمراه تعداد ثابتی از ركوردها را برمی گرداند. در چنين حالتی تغييرات و درج ركوردهای جديد در بانك در همان لحظه مشاهده نخواهد شد مگر اينكه مجددا درخواست بازيابی اطلاعات از بانك صادر شود.
پارامتر LockType، به ADO خواهد گفت كه چگونه با مسئله Lock در بانك اطلاعاتی رفتار نمايد. در حالت كلی می بايست برای اعمال تغييرات و يا درج ركوردهای جديد، پيش بينی های لازم را انجام داد. چراكه Lock ايجاد شده توسط يك كاربر می تواند باعث بروز مسائلی برای ساير كاربران گردد. مقدار اين پارامتر مطابق زير خواهد بود:
• adLockReadOnly: فقط خواندنی، امكان تغيير داده ها وجود نخواهد داشت.
• adLockPessimistic: قويترين نوع Lock است. ركوردهائی كه بدين صورت Lock خواهند شد توسط ساير كاربران قابل دستيابی نخواهند بود. ركوردها زمانيكه سرويس دهنده آنها را برمی گرداند Lock شده و تا زمانيكه شئ RecordSet وجود دارد، امكان استفاده از اين ركوردها برای سايرين وجود نخواهد داشت.
• adLockoptimistic: اين نوع Lock صرفا در زمان بهنگام سازی يك ركورد اعمال شده و بلافاصله ركورد از حالت Lock آزاد می گردد. بنابراين در مراحلی كه لازم است يك ركورد تغيير يابد می توان از اين نوع Lock استفاده كرد. و پس از اعمال تغييرات بصورت اتوماتيك، Lock آزاد خواهد شد.
• AdLockBatchOptimistic: اين نوع Lock مشابه Optimistic است با اين تفاوت كه آنها برای بهنگام سازی Batch مورد استفاده قرار می گيرند. در اين حالت مجموعه ای از ركوردها در يك مقطع زمانی بهنگام سازی خواهند شد ( بجای اينكه هر كورد بهنگام سازی گردد ). با توجه به نوع نرم افزار طراحی شده و ميزان محاوره ای بودن آن، می توان تصميم به استفاده از اين نوع Lock و يا Optimistic نمود.
آخرين پارامتر متد Recordset.Open، پارامتراختياری flag است. كه نوع Query را مشخص خواهد كرد ( Table,View,Stored Procedure ).
متد Move
پس از باز نمودن يك شئ RecordSet، با استفاده ازمتد Move، می توان در طول سطرهای موجود در شئ RecordSet با توجه به نوع cursor حركت كرد. شئ RecordSet دارای يك صفت با نام RecordCount بوده كه تعداد ركوردهای موجود در شئ RecordSet را مشخص می كند. تصور كنيد كه شئ RecordSet نظير يك جدول است با يك سطر خالی در ابتدا و يك سطر خالی در انتهای آن و اشاره گر ی كه در هر لحظه به يك ركورد اشاره می كند. در واقع با استفاده از متد Move، موقعيت اشاره گر فوق تغيير خواهد كرد ( اشاره گر حركت خواهد كرد) . شئ RecordSet دارای دو متد ديگر با نام EOF و BOF است كه زمان حضور اشاره گر در ابتدا و يا انتهای ركوردها را مشخص خواهند كرد. اين دو متد از نوع Boolean ( درست / نادرست ) هستند.
While NOT RecordSet.EOF در اين مقاله به بررسی برخی مثال های كاربردی از نحوه ارتباط ASP و ADO برای ايجاد وب سايت های متكی بر بانك های اطلاعاتی خواهيم پرداخت. قبل از پرداختن به مثال های مربوطه، در ابتدا لازم است كه يك بانك اطلاعاتی نمونه بهمراه يك جدول را تعريف كنيم. به كمك Access (نوع نسخه آن هر چيزی می تواند باشد) يك بانك اطلاعاتی با نام Students.mdb ايجاد و در آن صرفا يك جدول با نام Student كه شامل فيلدهای اطلاعاتی زير است، را تعريف می كنيم.
ID: شماره دانشجوئی يك دانشجو را در خود نگهداری خواهد كرد. فيلد فوق Primary Key خواهد بود.
FirstName: نام دانشجو را در خود نگهداری خواهد كرد.
LastName: نام خانوادگی دانشجو را در خود ذخيره خواهد كرد.
DateOfBirth: تاريخ تولد يك دانشجو را در خود نگهداری كرد.
Email: آدرس پست الكترونيكی دانشجو را در خود ذخيره خواهد كرد.
مثال ۱- بازيابی اطلاعات از بانك اطلاعاتی دانشجويان
در اين مثال جهت ارتباط با بانك اطلاعاتی از ODBC استفاده نشده است. برای بازيابی اطلاعات از بانك اطلاعاتی فوق از SQL SELECT استفاده می شود. متن برنامه بازيابی اطلاعات از بانك اطلاعاتی دانشجويان بصورت زير است.
<HTML>
<HEAD><TITLE>Student Records</TITLE></HEAD>
<BODY>
<%
Dim DBSet DB = Server.CreateObject ("ADODB.Connection")
DB.Open ("PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" + "C:\MyDb\Students.mdb")
Dim RSSet RS = Server.CreateObject ("ADODB.Recordset")
RS.Open "SELECT * FROM Students", DB
If RS.EOF And RS.BOF Then
Response.Write "There are 0 records."
Else
RS.MoveFirst
While Not RS.EOF
Response.Write RS.Fields ("FirstName")
Response.Write RS.Fields ("LastName")
Response.Write RS.Fields ("Email")
Response.Write "<HR>"
RS.MoveNext
Wend
End If
%>
</BODY>
</HTML>
مثال ۲- افزودن يک رکورد جديد
در اين مثال ركوردهای جديد را در بانك اطلاعاتی دانشجويان ذخيره خواهيم كرد. برای درج ركوردهای جديد در بانك اطلاعاتی می توان از INSERT INTO استفاده كرد. يكی ديگر از روش های درج ركورد در بانك اطلاعاتی استفاده از شئ RecordSet است كه بمراتب ساده تر مورد قبلی گفته شده است. در مثال فوق برای درج ركوردها در بانك اطلاعاتی از مورد دوم استفاده شده است. متن برنامه درج ركورد جديد در بانك اطلاعاتی دانشجويان بصورت زير است.
<HTML>
<HEAD>
<TITLE>Student Records</TITLE>
</HEAD>
<BODY>
<%
Dim DBSet DB = Server.CreateObject ("ADODB.Connection")
DB.Mode = adModeReadWrite
DB.Open ("PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" + C:\MyDb\Students.mdb")
Dim RSSet RS = Server.CreateObject ("ADODB.Recordset")
RS.Open "Students", DB, adOpenStatic, adLockPessimistic
RS.AddNew
RS ("FirstName") = "name"
RS ("LastName") = "family"
RS ("Email") = "name @domain.com"
RS ("DateOfBirth") = CDate("25 Mar, 2002")
RS.Update
%>
</BODY>
</HTML>
در مثال فوق ركورد دانشجوئی با نام "name" و نام خانوادگی "family" بهمراه آدرس پست الكترونيكی مربوطه و تاريخ تولد آن در بانك اطلاعاتی دانشجويان درج خواهد شد. اقلام اطلاعاتی مربوط به درج يك ركورد جديد را می توان با طراحی يك فرم از كاربران اخذ و پس از تكميل و ارسال فرم مربوطه، مقادير متناظر در هر يك از فيلدهای موجود در فرم اخذ اطلاعات به مقادير مربوطه در بانك اطلاعاتی نسبت داده شود (كار بسيار ساده ای است ! امتحان كنيد).
مثال ۳- بهنگام سازی ركوردهای بانك اطلاعاتی دانشجويان
در اين مثال با نحوه بهنگام سازی ركوردهای موجود در بانك اطلاعاتی دانشجويان آشنا خواهيم شد. متن برنامه بهنگام سازی ركورد دانشجوئی در بانك اطلاعاتی دانشجويان بصورت زير است.
<HTML>
<HEAD>
<TITLE>Student Records</TITLE>
</HEAD>
<BODY>
<%
Dim DBSet DB = Server.CreateObject ("ADODB.Connection")
DB.Mode = adModeReadWrite
DB.Open ("PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" + "C:\MyDb\Students.mdb")
Dim RSSet RS = Server.CreateObject ("ADODB.Recordset")
RS.Open "SELECT * FROM Students WHERE FirstName = ''name", DB, adOpenStatic, adLockPessimistic
RS ("Email") = "name@domain.com"
RS ("DateOfBirth") = CDate("26 Mar, 2001")
RS.Update
%>
</BODY>
</HTML>
در برنامه فوق ركورد دانشجوئی با نام "name" انتخاب و فيلدهای آدرس پست الكترونيكی (Email) و تاريخ تولد (DateIfBirth) آن تغيير و حاصل مجددا در بانك اطلاعاتی دانشجويان ثبت شده است.
مثال ۴- حذف يك ركورد
در اين مثال با نحوه حذف يك ركورد در بانك اطلاعاتی دانشجويان آشنا خواهيم شد. متن برنامه حذف يك ركورد از بانك اطلاعاتی دانشجويان بصورت زير است.
<HTML>
<HEAD>
<TITLE>Student Records</TITLE>
</HEAD>
<BODY>
<%
Dim DBSet DB = Server.CreateObject ("ADODB.Connection")
DB.Mode = adModeReadWrite
DB.Open ("PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" + "C:\MyDb\Students.mdb")
DB.Execute ("DELETE * FROM Students WHERE FirstName = 'name'")
%>
</BODY>
</HTML>
در مثال فوق ركورد دانشجوئی با نام "name" از بانك اطلاعاتی دانشجويان حذف شده است. در زمان حذف يك ركورد از بانك اطلاعاتی به دو نكته مهم می بايست توجه كرد: اولا امكان معروف Undo وجود ندارد. بنابراين ركوردی كه حذف می گردد، امكان برگرداندن آن وجود ندارد. ثانيا اگر در زمان اجرای DELETE ، عبارت WHERE حذف گردد، تمامی ركوردهای موجود در جدول حذف خواهند گرديد.
متدهای Sort و Search
با استفاده از متدهای شئ RecordSet، می توان عمليات مرتب سازی (Sort) و جستجو (Search) را انجام داد. برای مرتب سازی يك مجموعه از ركوردها نام فيلد مورد نظری را كه می خواهيم مرتب سازی بر اساس آن انجام شود را به صفت Sort نسبت خواهيم داد. مثلا اگر بخواهيم مجموعه ای از ركوردها را كه توسط اجرای SELECT * FROM PhoneBook برگردانده شده است را براساس نام خانوادگی (LastName) مرتب نمائيم، می توان دستور RecordSet.Sort = "LastName" را استفاده كرد. برای مرتب سازی ركوردها براساس بيش از يك فيلد بصورت RecordSet.Sort = "LastName, FirstName" عمل می نمائيم. برای مرتب سازی ركوردها بصورت صعودی ( پيش فرض است )، يا نزولی بصورت RecordSet.Sort = "LastName, FirstName DESC" عمل می کنيم.
برای جستجوی يك ركورد بخصوص در بين مجموعه ركوردهای برگردانده شده از متد Find شئ RecordSet استفاده می گردد. شرط جستجو را بصورتی كه در يك SQL Where است، مشخص خواهيم كرد و پس از اجرای متد Find، شئ RecordSet به اولين موردی كه پيدا كرده است اشاره خواهد كرد و در صورتيكه ركوردی پيدا نشود،EOF ارزش درست را پيدا خواهد كرد. متد Find بغير از شرطی كه نظير SQL WHERE برای آن مشخص می كنيم، می تواند دارای سه پارامتر اختياری ديگر باشد:
• SkipRecords: تعداد ركوردهائی را كه می بايست قبل از عمليات جستجو، صرفنظر (Skip) نمايد، مشخص خواهد كرد.
• SearchDirection: جهت حركت جستجو در مجموعه ركوردها را مشخص خواهد كرد. adSearchForward ( بسمت جلو) ويا adSearchBackward( از آخر بسمت اول )
• Start: تعداد ركوردهائی را كه می بايست برای جستجو شروع كرد مشخص می كند.
شئ Field
با اينكه تاكنون ما به شئ RecordSet بصورت يك جدول نگاه می كرديم، اما اين صرفا يك مدل فرضی برای راحتی تصور آن است. شئ RecordSet در حقيقت شامل يك بردار دو بعدی از شئ Field است. شئ Field شامل داده است. بنابراين هر شئ از اين نوع دارای يك اندازه، يك مقدار و يك نوع بخصوص است. شئ فوق همچنين دارای مجموعه ای از صفات است. در اكثر موارد شايد نيازی نباشد كه با صفات و متدهای شئ فوق مستقيما كار كنيم، اما مطالعه آنها برای موارد پيش بينی شده در طراحی صفحات ASP كه قصد ارتباط با بانك های اطلاعاتی از طريق ADO را دارند، توصيه می گردد.
شئ Connection
قبل از هر گونه ذخيره و بازيابی داده ها از بانك اطلاعاتی می بايست با ايجاد و مقدار دهی اوليه يك Connection زمينه لازم جهت ارتباط با بانك اطلاعاتی را بوجود آورد. در ADO با استفاده از شی Connection يك ارتباط با بانك اطلاعاتی ايجاد و پس از انجام عمليات دلخواه در رابطه با بانك اطلاعاتی و در زمانيكه به وجود آن ديگر نياز نباشد، می توان آن را حذف كرد. Open كردن يك ارتباط به بانك اطلاعاتی پروژه ای واحد با نام ( ADODB(ActiveX Data Objects Database بوده كه خود شامل تمامی اشياء ADO است. برای ايجاد يك Connection نظير ساير اشياء ASP از متد Server.CreateObject استفاده می گردد.
Dim Conn
Set Conn = Server.CreateObject("ADODB.Connection")
بصورت پيش فرض Connection فقط خواندنی می باشند، شما می توانيد وضعيت فوق را تغيير داده و در صورت نياز و بكمك صفات مربوط به شی فوق ارتباطاتی از نوع خواندنی / نوشتنی و يا فقط نوشتنی ايجاد نمائيد. در زمان استفاده از ADO می توان از مجموعه ای ثوابت كه دربردارنده مقادير متفاوتی برای آيتم های متفاوت می باشند و پيشاپيش تعريف شده اند استفاده كرد. اين ثوابت در فايلی با نام Adovbs.inc قرار دارند. بمنظور استفاده از ثوابت فوق در صفحات ASP خود، می بايست فايل فوق را بكمك دستور Include به برنامه های خود ملحق نمائيم.
<!-- #INCLUDE FILE="adovbs.inc" -->
اگر فايل adovbs.inc را توسط اديتوری نظير Notepad فعال نمائيد، ثوابت تعريف شده را بصورت مجموعه ای از گروهها مشاهده خواهيد كرد. پس از ايجاد يك Connection با بانك اطلاعاتی می توان نوع ( Mode ) ارتباط را بكمك استفاده از ثوابت تعريف شده مشخص نمود. در صورتيكه بخواهيم از بانك اطلاعاتی صرفا اطلاعاتی را بخوانيم از ثابت adModeRead ، فقط اطلاعاتی را در بانك اطلاعاتی بنويسيم از ثابت adoModeWrite و در نهايت در صورتيكه قصد داريم بطور همزمان اطلاعاتی را از بانك اطلاعاتی خوانده و در آن اطلاعات جديدی را نيز بنويسيم از ثابت adoModeReadWrite استفاده می گردد. توصيه می گردد با توجه به نوع رفتاری كه با بانك اطلاعاتی خواهيم داشت آن را باز نمائيم چراكه در صورتيكه صرفا قصد خواندن و يا نوشتن را در يك بانك اطلاعاتی داشته باشيم و نخواهيم دو عمليات را با هم انجام دهيم، باز كردن بانك اطلاعاتی بصورت هم خواندنی و هم نوشتنی ( adoModeReadWrite ) سرعت دستيابی به بانك اطلاعاتی را كاهش خواهد داد.
ConnectionString
پس از تعيين Mode، می بايست صفت Connectionstring مربوط به شی Connection را مقدار دهی مناسب نمود. صفت فوق دارای چندين بخش بوده كه می بايست مشخص گردند: نام Provider، نام سرويس دهنده بانك اطلاعاتی، نام بانك اطلاعاتی كه قصد استفاده از آن را داريد، User Id لازم جهت اتصال به بانك اطلاعاتی (UID)، رمز عبور برای كاربرخاص ( PWD ).
هر يك از بخش های فوق توسط علامت ";" از هم جدا می شوند. مثلا در ساده ترين حالت می توانيد از يك Data Source Name يا DSN يا مربوط به ODBC، يك User ID، و يك رمز عبور جهت اتصال به بانك اطلاعاتی استفاده نمائيد. يك DSN خود شامل نام Provider، نام سرويس دهنده بانك اطلاعاتی و نام بانك اطلاعاتی بوده و ديگر نيازی به مشخص نمودن مجدد آنها نخواهد بود. به مثال زير توجه فرمائيد.
Dim Conn
Set Conn = Server.Create0bject("ADODB.Connection")
Conn.Mode = adModeReadWrite
Conn.ConnectionString = "DSN=myDSN;UID=Javad;PWD=7474;"
روش فوق بهترين حالت ايجاد يك ارتباط نيست زيرا DSN بصورت پيش فرض از MSDASQL Provider استفاده می كند. اما JET OLEDB Provider بمراتب سريعتر و قابليت های بيشتری را دارا است. بنابراين می توان جهت ارتباط با بانك اطلاعاتی مطابق زير عمل نمود:
Dim Conn, ConnStr
ConnStr= "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" + Server.MapPath(Path2DB)
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Mode = adModeReadWrite
Conn.ConnectionString = ConnStr
ConnectionString شامل نام Provider، نام سرويس دهنده بانك اطلاعاتی و نام بانك اطلاعاتی است. در مثال فوق از تابع Server.MapPath برای ترجمه مسير مجازی به مسير واقعی استفاده شده است. مثلا يك بانك اطلاعاتی موجود درwww.Test.com/test.mdb (http://pnu-club.com/redirector.php?url=http%3A%2F%2Fwww.test.com%2Ftes t.mdb) می تواند بصورت واقعی در مسير E:\web\Mydatabase\Test.mdb قرار گرفته باشد. تابع Server.MapPath آدرس نوع اول را به آدرس نوع دوم ترجمه خواهد كرد. توجه داشته باشيم كه شی ADODB.Connection نيازمند آگاهی از مسير واقعی بانك اطلاعاتی است. فراموش نكنيم كه قبل از باز نمودن Connection، تمامی تغييرات لازم بر روی صفت های مربوطه اعمال گردد. در صورتيكه بخواهيم پس از ايجاد ارتباط با بانك اطلاعاتی يك يا چند صفت مرتبط را تغيير دهيم، می بايست در ابتدا ارتباط خود را با بانك اطلا عاتی قطع (Connection، بسته گردد) و در ادامه تغييرات لازم را از طريق صفات مربوطه اعمال و مجددا Connection را برقرار نمود.
بمنظور باز نمودن يك Connection از متد Open مربوط به شئ Connection استفاده می گردد.
متد Connection.Open
در صورتيكه متد فوق بدون خطا اجرا گردد، يك ارتباط كاری ( عملياتی) با بانك اطلاعاتی ايجاد شده است.
متد Connection.Execute
برای بازيابی داده ها از يك بانك اطلاعاتی توسط ADO سه روش عمده وجود دارد. تمامی آنها در مرحله اول نياز به ارتباط با بانك اطلاعاتی خواهند داشت. ساده ترين حالت استفاده از متد Execute مربوط به شی Connection است. متد فوق سه پارامتر را خواهد داشت:- يك دستور SQL، يا Query، Table، View يا نام يك Stored Procedure كه توسط پارامتر CommandText مشخص خواهد شد.
• يك متغير با نام RecordsAffected، كه شامل تعداد ركوردهائی خواهد بود كه با توجه به Query اجرا شده توسط متد Execute مشخص می شود.
• يك ثابت اختياری با نام CommandTypeEnum كه به بانك اطلاعاتی خواهد گفت چه نوع عبارت و يا Query را می خواهيد اجرا نمائيد و اينكه يك شی Recordset را برگرداند يا خير.
پس از اجرای متد Execute ( به هر روش ممكن )، ركوردهای برگردانده شده در شئ RecordSet برگردانده خواهند شد. در صورتيكه از دستور SELECT استفاده شود ركوردهای برگردانده شده در شی RecordSet قرار خواهند گرفت. اما زمانيكه از دستورات INSERT و يا UPDATE استفاده گردد رکوردی باز گردانده نخواهد شد.
شئ RecordSet
از شی RecordSet جهت نگهداری رکوردها يا جدول دريافتی استفاده می گردد. اين شئ نظير يك جدول بانك اطلاعاتی دارای سطرها و ستون هائی است. در حقيقت شئ فوق يك تصور مجازی از يك جدول خواهد داد و بصورت فيزيكی يك جدول نيست. چراكه مقادير مورد نظری كه در ستون های اين شئ قرار می گيرد ممكن است حاصل تركيب (Join) چندين جدول ديگر باشند.
متد RecordSet.Open
در صورتيكه در هنگام استفاده از شئ RecordSet به هر نوع Cursor ( اشاره گری به هر يك از سطرهای موجود در جدول ) نياز داشته باشيد ( صرفا نه يك Cursor كه بصورت Forward-Only و يا Read-Only باشد ) می بايست به جای استفاده از متد Execute مربوط به شی Connection، مستقيما بانك اطلاعاتی را باز کنيد. شئ RecordSet نيز دارای متدی با نام Open است كه چندين پارامتر را بعنوان پارامتر اخذ می كند.
Recordset.Open CommandText, Connection|ConnectionString, Cursor-Type, LockType, Options
CommandText شامل SQL query بوده، Connection|ConnectionString شامل يك رجوع به شئ Connection باز شده و يا يك پارامتر معتبر Connectionstring است. پارامتر CursorType مقدار خود را از ثابتی با نام adCursorTypeEnm مطابق زير اخذ خواهد كرد:
• adopenForwardOnly: يك Cursor كه فقط امكان حركت بسمت جلو را دارد، برمی گرداند. ( پيش فرض). اگر نوع Cursor را مشخص ننمائيد، ADO همواره Cursor از اين نوع را بر می گرداند. همانگونه كه از نام آن مشخص است، صرفا می توان بسمت جلو در شئ RecordSet حركت نمود.
• AdOpenKeyset: يك Cursor از نوع Keyset را برمی گرداند. در چنين حالتی می توان جهت و نوع حركت را به هر نوع دلخواه انتخاب نمود (اولين ركورد، آخرين ركورد، بسمت جلو، بسمت عقب...). سرويس دهنده برای هر يك از سطرهای موجود در شئ RecordSet پس از اجرای Query يك Bookmark، ايجاد می كند. اين Bookmark ها تا زمانيكه شئ Recordset حيات دارد تغيير نخواهند كرد بنابراين در صورتی كه يك ركورد جديد توسط كاربر ديگری در بانك اطلاعاتی در آن زمان درج گردد، آن رکورد جديد برای ما قابل رؤيت نخواهد بود.
• adOpenDynamic: يك Cursor پويا را برمی گرداند. اين نوع Cursor مشابه Keyset است با اين تفاوت كه امكان مشاهده ركوردهای جديد نيز وجود خواهد داشت. يك Cursor پويا بصورت پيوسته ركوردهای جديد و يا تغيير يافته را بررسی و حاصل را در شی RecordSet بصورت پويا منعكس خواهد كرد.
• adOpenStatic: يك Cursor ايستا بهمراه تعداد ثابتی از ركوردها را برمی گرداند. در چنين حالتی تغييرات و درج ركوردهای جديد در بانك در همان لحظه مشاهده نخواهد شد مگر اينكه مجددا درخواست بازيابی اطلاعات از بانك صادر شود.
پارامتر LockType، به ADO خواهد گفت كه چگونه با مسئله Lock در بانك اطلاعاتی رفتار نمايد. در حالت كلی می بايست برای اعمال تغييرات و يا درج ركوردهای جديد، پيش بينی های لازم را انجام داد. چراكه Lock ايجاد شده توسط يك كاربر می تواند باعث بروز مسائلی برای ساير كاربران گردد. مقدار اين پارامتر مطابق زير خواهد بود:
• adLockReadOnly: فقط خواندنی، امكان تغيير داده ها وجود نخواهد داشت.
• adLockPessimistic: قويترين نوع Lock است. ركوردهائی كه بدين صورت Lock خواهند شد توسط ساير كاربران قابل دستيابی نخواهند بود. ركوردها زمانيكه سرويس دهنده آنها را برمی گرداند Lock شده و تا زمانيكه شئ RecordSet وجود دارد، امكان استفاده از اين ركوردها برای سايرين وجود نخواهد داشت.
• adLockoptimistic: اين نوع Lock صرفا در زمان بهنگام سازی يك ركورد اعمال شده و بلافاصله ركورد از حالت Lock آزاد می گردد. بنابراين در مراحلی كه لازم است يك ركورد تغيير يابد می توان از اين نوع Lock استفاده كرد. و پس از اعمال تغييرات بصورت اتوماتيك، Lock آزاد خواهد شد.
• AdLockBatchOptimistic: اين نوع Lock مشابه Optimistic است با اين تفاوت كه آنها برای بهنگام سازی Batch مورد استفاده قرار می گيرند. در اين حالت مجموعه ای از ركوردها در يك مقطع زمانی بهنگام سازی خواهند شد ( بجای اينكه هر كورد بهنگام سازی گردد ). با توجه به نوع نرم افزار طراحی شده و ميزان محاوره ای بودن آن، می توان تصميم به استفاده از اين نوع Lock و يا Optimistic نمود.
آخرين پارامتر متد Recordset.Open، پارامتراختياری flag است. كه نوع Query را مشخص خواهد كرد ( Table,View,Stored Procedure ).
متد Move
پس از باز نمودن يك شئ RecordSet، با استفاده ازمتد Move، می توان در طول سطرهای موجود در شئ RecordSet با توجه به نوع cursor حركت كرد. شئ RecordSet دارای يك صفت با نام RecordCount بوده كه تعداد ركوردهای موجود در شئ RecordSet را مشخص می كند. تصور كنيد كه شئ RecordSet نظير يك جدول است با يك سطر خالی در ابتدا و يك سطر خالی در انتهای آن و اشاره گر ی كه در هر لحظه به يك ركورد اشاره می كند. در واقع با استفاده از متد Move، موقعيت اشاره گر فوق تغيير خواهد كرد ( اشاره گر حركت خواهد كرد) . شئ RecordSet دارای دو متد ديگر با نام EOF و BOF است كه زمان حضور اشاره گر در ابتدا و يا انتهای ركوردها را مشخص خواهند كرد. اين دو متد از نوع Boolean ( درست / نادرست ) هستند.
While NOT RecordSet.EOF در اين مقاله به بررسی برخی مثال های كاربردی از نحوه ارتباط ASP و ADO برای ايجاد وب سايت های متكی بر بانك های اطلاعاتی خواهيم پرداخت. قبل از پرداختن به مثال های مربوطه، در ابتدا لازم است كه يك بانك اطلاعاتی نمونه بهمراه يك جدول را تعريف كنيم. به كمك Access (نوع نسخه آن هر چيزی می تواند باشد) يك بانك اطلاعاتی با نام Students.mdb ايجاد و در آن صرفا يك جدول با نام Student كه شامل فيلدهای اطلاعاتی زير است، را تعريف می كنيم.
ID: شماره دانشجوئی يك دانشجو را در خود نگهداری خواهد كرد. فيلد فوق Primary Key خواهد بود.
FirstName: نام دانشجو را در خود نگهداری خواهد كرد.
LastName: نام خانوادگی دانشجو را در خود ذخيره خواهد كرد.
DateOfBirth: تاريخ تولد يك دانشجو را در خود نگهداری كرد.
Email: آدرس پست الكترونيكی دانشجو را در خود ذخيره خواهد كرد.
مثال ۱- بازيابی اطلاعات از بانك اطلاعاتی دانشجويان
در اين مثال جهت ارتباط با بانك اطلاعاتی از ODBC استفاده نشده است. برای بازيابی اطلاعات از بانك اطلاعاتی فوق از SQL SELECT استفاده می شود. متن برنامه بازيابی اطلاعات از بانك اطلاعاتی دانشجويان بصورت زير است.
<HTML>
<HEAD><TITLE>Student Records</TITLE></HEAD>
<BODY>
<%
Dim DBSet DB = Server.CreateObject ("ADODB.Connection")
DB.Open ("PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" + "C:\MyDb\Students.mdb")
Dim RSSet RS = Server.CreateObject ("ADODB.Recordset")
RS.Open "SELECT * FROM Students", DB
If RS.EOF And RS.BOF Then
Response.Write "There are 0 records."
Else
RS.MoveFirst
While Not RS.EOF
Response.Write RS.Fields ("FirstName")
Response.Write RS.Fields ("LastName")
Response.Write RS.Fields ("Email")
Response.Write "<HR>"
RS.MoveNext
Wend
End If
%>
</BODY>
</HTML>
مثال ۲- افزودن يک رکورد جديد
در اين مثال ركوردهای جديد را در بانك اطلاعاتی دانشجويان ذخيره خواهيم كرد. برای درج ركوردهای جديد در بانك اطلاعاتی می توان از INSERT INTO استفاده كرد. يكی ديگر از روش های درج ركورد در بانك اطلاعاتی استفاده از شئ RecordSet است كه بمراتب ساده تر مورد قبلی گفته شده است. در مثال فوق برای درج ركوردها در بانك اطلاعاتی از مورد دوم استفاده شده است. متن برنامه درج ركورد جديد در بانك اطلاعاتی دانشجويان بصورت زير است.
<HTML>
<HEAD>
<TITLE>Student Records</TITLE>
</HEAD>
<BODY>
<%
Dim DBSet DB = Server.CreateObject ("ADODB.Connection")
DB.Mode = adModeReadWrite
DB.Open ("PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" + C:\MyDb\Students.mdb")
Dim RSSet RS = Server.CreateObject ("ADODB.Recordset")
RS.Open "Students", DB, adOpenStatic, adLockPessimistic
RS.AddNew
RS ("FirstName") = "name"
RS ("LastName") = "family"
RS ("Email") = "name @domain.com"
RS ("DateOfBirth") = CDate("25 Mar, 2002")
RS.Update
%>
</BODY>
</HTML>
در مثال فوق ركورد دانشجوئی با نام "name" و نام خانوادگی "family" بهمراه آدرس پست الكترونيكی مربوطه و تاريخ تولد آن در بانك اطلاعاتی دانشجويان درج خواهد شد. اقلام اطلاعاتی مربوط به درج يك ركورد جديد را می توان با طراحی يك فرم از كاربران اخذ و پس از تكميل و ارسال فرم مربوطه، مقادير متناظر در هر يك از فيلدهای موجود در فرم اخذ اطلاعات به مقادير مربوطه در بانك اطلاعاتی نسبت داده شود (كار بسيار ساده ای است ! امتحان كنيد).
مثال ۳- بهنگام سازی ركوردهای بانك اطلاعاتی دانشجويان
در اين مثال با نحوه بهنگام سازی ركوردهای موجود در بانك اطلاعاتی دانشجويان آشنا خواهيم شد. متن برنامه بهنگام سازی ركورد دانشجوئی در بانك اطلاعاتی دانشجويان بصورت زير است.
<HTML>
<HEAD>
<TITLE>Student Records</TITLE>
</HEAD>
<BODY>
<%
Dim DBSet DB = Server.CreateObject ("ADODB.Connection")
DB.Mode = adModeReadWrite
DB.Open ("PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" + "C:\MyDb\Students.mdb")
Dim RSSet RS = Server.CreateObject ("ADODB.Recordset")
RS.Open "SELECT * FROM Students WHERE FirstName = ''name", DB, adOpenStatic, adLockPessimistic
RS ("Email") = "name@domain.com"
RS ("DateOfBirth") = CDate("26 Mar, 2001")
RS.Update
%>
</BODY>
</HTML>
در برنامه فوق ركورد دانشجوئی با نام "name" انتخاب و فيلدهای آدرس پست الكترونيكی (Email) و تاريخ تولد (DateIfBirth) آن تغيير و حاصل مجددا در بانك اطلاعاتی دانشجويان ثبت شده است.
مثال ۴- حذف يك ركورد
در اين مثال با نحوه حذف يك ركورد در بانك اطلاعاتی دانشجويان آشنا خواهيم شد. متن برنامه حذف يك ركورد از بانك اطلاعاتی دانشجويان بصورت زير است.
<HTML>
<HEAD>
<TITLE>Student Records</TITLE>
</HEAD>
<BODY>
<%
Dim DBSet DB = Server.CreateObject ("ADODB.Connection")
DB.Mode = adModeReadWrite
DB.Open ("PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" + "C:\MyDb\Students.mdb")
DB.Execute ("DELETE * FROM Students WHERE FirstName = 'name'")
%>
</BODY>
</HTML>
در مثال فوق ركورد دانشجوئی با نام "name" از بانك اطلاعاتی دانشجويان حذف شده است. در زمان حذف يك ركورد از بانك اطلاعاتی به دو نكته مهم می بايست توجه كرد: اولا امكان معروف Undo وجود ندارد. بنابراين ركوردی كه حذف می گردد، امكان برگرداندن آن وجود ندارد. ثانيا اگر در زمان اجرای DELETE ، عبارت WHERE حذف گردد، تمامی ركوردهای موجود در جدول حذف خواهند گرديد.
متدهای Sort و Search
با استفاده از متدهای شئ RecordSet، می توان عمليات مرتب سازی (Sort) و جستجو (Search) را انجام داد. برای مرتب سازی يك مجموعه از ركوردها نام فيلد مورد نظری را كه می خواهيم مرتب سازی بر اساس آن انجام شود را به صفت Sort نسبت خواهيم داد. مثلا اگر بخواهيم مجموعه ای از ركوردها را كه توسط اجرای SELECT * FROM PhoneBook برگردانده شده است را براساس نام خانوادگی (LastName) مرتب نمائيم، می توان دستور RecordSet.Sort = "LastName" را استفاده كرد. برای مرتب سازی ركوردها براساس بيش از يك فيلد بصورت RecordSet.Sort = "LastName, FirstName" عمل می نمائيم. برای مرتب سازی ركوردها بصورت صعودی ( پيش فرض است )، يا نزولی بصورت RecordSet.Sort = "LastName, FirstName DESC" عمل می کنيم.
برای جستجوی يك ركورد بخصوص در بين مجموعه ركوردهای برگردانده شده از متد Find شئ RecordSet استفاده می گردد. شرط جستجو را بصورتی كه در يك SQL Where است، مشخص خواهيم كرد و پس از اجرای متد Find، شئ RecordSet به اولين موردی كه پيدا كرده است اشاره خواهد كرد و در صورتيكه ركوردی پيدا نشود،EOF ارزش درست را پيدا خواهد كرد. متد Find بغير از شرطی كه نظير SQL WHERE برای آن مشخص می كنيم، می تواند دارای سه پارامتر اختياری ديگر باشد:
• SkipRecords: تعداد ركوردهائی را كه می بايست قبل از عمليات جستجو، صرفنظر (Skip) نمايد، مشخص خواهد كرد.
• SearchDirection: جهت حركت جستجو در مجموعه ركوردها را مشخص خواهد كرد. adSearchForward ( بسمت جلو) ويا adSearchBackward( از آخر بسمت اول )
• Start: تعداد ركوردهائی را كه می بايست برای جستجو شروع كرد مشخص می كند.
شئ Field
با اينكه تاكنون ما به شئ RecordSet بصورت يك جدول نگاه می كرديم، اما اين صرفا يك مدل فرضی برای راحتی تصور آن است. شئ RecordSet در حقيقت شامل يك بردار دو بعدی از شئ Field است. شئ Field شامل داده است. بنابراين هر شئ از اين نوع دارای يك اندازه، يك مقدار و يك نوع بخصوص است. شئ فوق همچنين دارای مجموعه ای از صفات است. در اكثر موارد شايد نيازی نباشد كه با صفات و متدهای شئ فوق مستقيما كار كنيم، اما مطالعه آنها برای موارد پيش بينی شده در طراحی صفحات ASP كه قصد ارتباط با بانك های اطلاعاتی از طريق ADO را دارند، توصيه می گردد.