ارتباط 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 به برنامه های خود ملحق نمائیم.
اگر فایل 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 می تواند بصورت واقعی در مسیر 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
"Do something
RecordSet.MoveNext
Wend
متدهای 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 را دارند، توصیه می گردد.