فهرست مطالب
۱-۱ کار با رکورد های پایگاه داده از طریق ADO 2
فهرست اشکال
فهرست جداول
جدول ۱‑۱ : خواص کنترل های برنامه. ۲۲
PHRASE | Abb& Acr |
Microsoft ActiveX Data Objects | ADO |
Object Linking and Embedding, Database | OLEDB or OLE-DB |
پیشگفتار
آشنایی با Visual C++
کار با رکورد های پایگاه داده از طریق ADO
در این بخش با تکنولوژی ADO[۱] مایکرسافت آشنا خواهیم شد. این تکنولوژی که به طور خاص برای تمام زبانهای برنامه نویسی و دستوری[۲] میکروسافت طراحی شده ، برنامه نویسان را به چالشی جدید ( هر چند آشنا ) می خواند.
در این مبحث ، مطالب زیر آموزش داده می شود :
- ADO چیست و چگونه از تکنولوژی OLEDB برای دسترسی به پایگاه داده استفاده می کند.
- چگونه می توانید در عرض چند دقیقه با کنترل های ActiveX یک برنامه ساده ADO بنویسید .
- چکونه با کنترل های معمولی برنامه تان را کامل کنید .
- چگونه می توانید با استفاده از ماکروهای ویژه ADO یک کلاس رکورد دست دلخواه بسازید .
ADO چیست ؟
قریب به دو سال پیش ، میکروسافت تکنولوژی پایگاه داده جدیدی بنام OLEDB[۳] را توسعه داد. این تکنولوژی فقط یک روش ساده دسترسی به پایگاه های داده نبود و طوری طراحی شده بود که بتواند داده ها را از هر منبعی بخواند. از طریق OLEDB حتی می توان پیام های پست الکترونیک[۴] ، کاربرگ ها و فایل ها را بازیابی کرد. در واقع هر چیزی که داده داشته باشد را می توان با OLEDB خواند. قلب تکنولوژی OLEDB همان چیزیست که سالها بنام سیستم فایل شی، گرا[۵] در بطن کایرو[۶] ، که سلف ویندوز ان تی ۰/۵ محسوب می شود، به کار کرفته شده است. همانطور که حدس زدید وسعت بیش از حد تکنولوژی OLEDB باعث می شد تا بسیار پیچیده شود و کار کردن با آن چندان آسان نباشد و از همین جا بود که ADO پا به میدان گذاشت. ADO در حقیقت لایه ای بر فراز OLEDB ، بمنظور ارائه یک سیستم ساده دسترسی به پایگاه های داده ، می باشد.
یکی از اهداف ADO ، ایجاد کنترلی برای دسترسی به داده ها در صفحه وب بود. بدین ترتیب دیگر صفحات وب برای کار با یک رکوردست[۷] نیازی به خواندن تک تک رکوردها ندارند و می توانند براحتی در آن مانور دهند. همین توانایی ADO بود که باعث شد میکروسافت آن را با کاوشگر وب خود یعنی Internet Explorer ، ( از ویرایش ۴.۰ به بعد ) یکپارچه سازد.
اشیاء ADO
برای آن که ADO در زبان های دستوری ( مانند VBScript ) یا محیط های برنامه نویسی ( مانند Visual Basic ) به سادگی قابل استفاده باشد ، میکروسافت تصمیم گرفت تعداد اشیاء[۸] آن را در حداقل ممکن نگه دارد. به همین دلیل ، ADO دارای اشیاء محدودیست :
- Connection
- Command
- Parameter
- Recordset
- Field
علاوه بر این اشیاء ADO دارای سه مجموعه[۹] از اشیاء Error ، Parameter و Field می باشد.
شی ء Connection
از شی ء Connection برای برقراری اتصال با یک پایگاه داده و حفظ آن استفاده می شود. قبل از برقراری اتصال این شی ء ، با اطلاعات لازم از قبیل محل پایگاه داده ، ID کاربر[۱۰] و کلمه رمز[۱۱] وی پیکربندی می شود. پس از پیکربندی این شی ء ، روش باعث برقراری اتصال به پایگاه داده خواهد شد. برای قطع ارتباط با پایگاه داده می توانید از روش استفاده کنید. اما هرگاه شی ء Connection از میدان دید برنامه خارج شود ، ارتباط خود بخود قطع خواهد شد.
شی ء Connection عملکرد های سطح بالایی از قبیل کنترل نقل و انتقالات[۱۲] را هم از طریق روشهایی مانند ، 'و پشتیبانی می کند.
شی ء Error
هر گاه خطایی در یک پایگاه داده روی دهد ، اطلاعات آن در شی ء Error کنترل ADO قرار خواهد گرفت. دقت کنید که این اطلاعات خطا مربوط به پایگاه داده می باشد و مربوط به شی ء ADO نیست.
شی ء Command
از شی ء Command برای اجرای فرامین پایگاه داده[۱۳] استفاده می شود. از این شی ء می توان برای اجرای دستورات SQL یا روال ذخیره شده[۱۴] استفاده کرد. وقتی که یک دستور تعدادی رکورد بر می گرداند، برای ذخیره کردن آنها باید شی ء Command به یک شی ء Recordset متصل شود.
اغلب روال های ذخیره شده به آرگومانهایی نیاز دارند. برای ارسال این آرگومانها باید به همان تعداد اشیاء Parameter به شی ء Command متصل کنید. هر شی ء Parameter دارای نام آرگومانیست که مقدار آن را در خود نگه داشته است.
شی ء Parameter
از شی ء Parameter برای ارسال آرگومان به روال های ذخیره شده ای که به آرگومان نیاز دارند استفاده می شود. این اشیاء باید به شیء Command تابع مربوط متصل شوند.
شی ء Recordset
رکوردهایی که هر دستور Command بر می گرداند در یک شیء Recordset قرار خواهند گرفت. روش استفاده ار رکوردست شی ء ADO بسیار شبیه استفاده از آن در سایر تکنولوژیهای پایگاه داده است. برای دسترسی به فیلد های هر شیء Recordset می توانید از شی ء Field استفاده کنید. بعد از به روز آوری رکوردست می توانید با همان شی ء Recordset پایگاه داده را به روز نمایید. برای اضافه یا حذف کردن رکوردها هم باید از همین شی، استفاده کنید.
شی ء Field
هر شی ء Field نماینده یک ستون در Recordset است. این شیء علاوه بر نام و مقدار ستون ( فیلد ) نحوه نمایش آن را هم در خود دارد. از ADO باید با زبانهای دستوری کار کند و در این زبان ها فقط نوع داده Varaint وجود دارد ، شی ء Field همیشه یک مقدار از نوع Variant در خود نگه می دارد. این مقدار همیشه هنگام نوشته شدن در پایگاه داده به طور خودکار به نوع داده مناسب تبدیل خواهد شد.
استفاده از کنترل ADO
برای استفاده از کنترل ADO در برنامه های Visual C ++ دو راه وجود دارد. راه آسان تر استفاده از کنترل های ActiveX به برنامه خود اضافه کنید ( شکل ۱‑۱ ، را نگاه کنید ).
بعد از اضافه کردن کنترل ADO به پروژه و قراردادن آن روی پنجره برنامه ، باید از طریق دیالوگ خواص آن را پیکر بندی کنید ( شکل ۱‑۲ ) منبع داده ای که این کنترل رکوردهای خود را از آن استخراج می کند را هم باید در همین دیالوگ تعیین کنید ( شکل ۱‑۳ ).
برای استفاده موثر از کنترل ADO باید از کنترل های سازگار با ADO ، مانند کنترل Microsaft Data grid ، استفاده کنید. وقتی این قبیل کنترل ها را روی پنجره برنامه قرار می دهید باید کنترل ADO را به عنوان منبع داده آنها معرفی کنید. (شکل ١۵ – ۴ ). اگر این کنترل ها از انواعی باشند که فقط یک فیلد را می پذیرند ، باید فیلد مربوط را هم تعیین کنند.
بعد از پیکر بندی تمام کنترل های برنامه ، می توانید برنامه را کامپایل و اجرا کنید. بله ، بدون نوشتن حتی یک خط کد می توانید از طریق ADO به پایگاههای داده دسترسی داشته باشید (به شکل ۱۵-۵ نگاه کنید).
ساختن یک برنامه پایگاه داده به همین سادگیست : کنترل های مورد نیاز را روی پنجره برنامه قرار دهید و به آنها بگویید منبع داده ها کجاست. اما جنبه منفی کنترل های ADO چیست؟ اول آنکه ، این روش یک بار اضافی غیر لازم به برنامه تحمیل می کند چون برای هر جستجوی SQL یا جدول پایگاه داده یک کنترل ADO نیاز دارید. هر یک از این کنترل ها به یک اتصال به پایگاه داده نیاز دارند و این در پایگاه های داده ای که دارای تعداد معدودی اتصال هستند باعث بروز اشکال خواهد شد(حتی بدون در نظر گرفتن بار اضافی این کنترل ها ). از طرف دیگر چون ADO تکنولوژی بسیار جدیدیست، همه کنترل های با ADO سازگار نیستند. برخی از کنترل ها می توانند رکورد ها را نمایش دهند ولی اجازه دستکاری در پایگاه داده را نمی دهند و برخی دیگر حتی این کار را نمی توانند بکنند.
استفاده از ADO DLL
اگر به سلسله مراتب کلاس های MFC نگاه کنید ، متوجه خواهید شد که در آن هیچ کلاسی برای ADO وجود ندارد. اما اگر از کنترل ADO استفاده نکنیم چه راه دیگری در پیش رو داریم ؟ آیا خودمان باید کلاس های لازم را بسازیم ؟ خیر، میکروسافت راه دیگری برای ایجاد و استفاده از کلاس هایADO از طریق یک دستور پیش کامپایلر[۱۵] بنام import# ، ارائه نموده است.
با این دستور ، که از ویرایش پنجم به آن اضافه شده است، می توانید از ActiveX DLL هایی که از واسط Dispath استفاده می کنند، در برنامه خود استفاده کنید. این دستور به کامپایلر می گوید که مشخص شده را به برنامه وارد[۱۶] کرده و بعد از استخراج اطلاعات لازم از آن ، فایل های سرباره مورد نیاز را ضمیمه کند. این فایل ها که پسوند' و دارند در همان دایرکتوری فایل های خروجی برنامه (دایرکتوریهای Release و Debug ) قرار می گیرند در این فایل تعریف کلاس تمام اشیایی که فایل را به پروژه ضمیمه کند و دیگر نیازی به ضمیمه کردن فایل آن وجود نخواهد داشت.
برای وارد کردن ADO DLL به برنامه ، کد ذیل را در ابتدای فایل سرباره ای که اشیاء پایگاه داده در آن تعریف شده اند قرار دهید:
درخط اول این کد ، یک ثابت مورد نیاز برای کار با ADO تعریف شده است. در خط دوم به برنامه وارد شده است. بعد از قید نام فایل ، دو صفت دیگر با دستور به برنامه اضافه شده است. اولی فضای نام DLL را تغییر می دهد. صفت دوم ، rename ، یکی از عناصر فایل های سرباره را تغییر می دهد. علت این تغییر جلوگیری از تداخل با سایر نام هاست. اگر به فایل سرباره نگاه کنید ، خواهید دید که نام عنصر مشخص شده تغییر نکرده است ، ولی کامپایلر بعد از خواندن این فایل آن را تغییر خواهد داد و در خط آن فایل سرباره ADO ،که در آن تعدادی از ماکروهای لازم برای نوشتن برنامه های ADO تعریف شده اند ، به برنامه ضمیمه شده است.
اتصال به پایگاه داده
قبل از آن که بتوانید از اشیا، ADO استفاده کنید ، باید محیط را برای برنامه آماده کنید. اینکار با استفاده از یک تابع API بنام Colnitialize با پارامتر انجام می شود :
و بعد از آن می توان از اشیاء ADO استفاده کرد. اگر از این دستور استفاده نکنید ، یا بعد از شروع کار با یک شی ADO آن را به کار گیرید ، هنگام اجرای برنامه با یک خطای COM مواجه خواهید شد.
بعد از آنکه کارتان با اشیا، ADO به پایان رسید ، باید محیط COM را با تابع CoUninitialize ببندید :
این تابع محیط COM را بسته و اجازه می دهد تا برنامه طبق روال عادی پایان یابد.
بعد از آماده کردن محیط COM ، نوبت به برقراری اتصالی با پایگاه داده می رسد. بهترین راه ، برای اینکار ، نه تعریف یک شی ء Connection بلکه ، تعریف یک شیء (-Connectionptr) Connection است. بعد از تعریف اشاره گر شی ء Connection ، می توانید با تابع Createlnstance یک وهله از آن را ایجاد کرده و آماده کار کنید. تابع Createlnstance فقط یک آرگومان (UUID شی ء Connection ) می گیرد :
نکته : هنگام کار با این اشیاء وتوابع باید مراقب تعداد زیر خط های جلوی نام آنها باشید ، شی ء فقط یک زیر خط دارد ، در حالی که تابع دارای دو زیر خط است.
همین که این شیء را ایجاد کردید ، می توانید با تابع Open اتصال با پایگاه داده را بر قرار کنید. تابع Open چهار آرگومان می گیرد. آرگومان اول رشته تعریف اتصال[۱۷] است. این رشته یک منبع داده OLEDB برای پایگاه داده مورد نظر می رساند. ممکن است این پایگاه داده یک درایو ODBC OLEDB باشد ، که در آن OLEDB به عنوان یک لایه بر روی منبع داده ODBC عمل می کند ( برنامه درس امروز از این روش استفاده خواهد کرد ) اگر پایگاه داده ای که می خواهید به آن متصل شوید از نوع SQL Server یا Oracle است ، این رشته می تواند یک اتصال مستقیم به واسط OLEDB آنها باشد. آرگومان دوم ، ID کاربر برای اتصال به پایگاه داده است. سومین آرگومان ،کلمه رمز کاربر در آن پایگاه داده است. آرگومان چهارم نوع کرسر مورد استفاده در پایگاه داده است. انواع مختلف کرسر در فایل سرباره msADO 15tlh ( که با دستور ایجاد شده ) تعریف شده اند. در ذیل یک دستور Open را برای اتصال به یک پایگاه داده ODBC که نیازی به نام کاربر و کلمه رمز ندارد ، می بینید :
اجرای فرامین و بازیابی داده ها
بعد از برقراری اتصال به پایگاه داده می توانید با استفاده از شی ء Command به آن فرامین SQL بفرستید. این روش معمول اجرای دستورات SQL در ADO است. برای ایجاد شی ء Command باید همان مراحل ایجاد شی ء Connection را دنبال کنید : تعریف یک متغیر اشاره گر به و Command و سپس ایجاد یک وهله از آن با استفاده از UUID :
سپس ، با فرض آن که قبلا اتصال به پایگاه داده برقرار شده ، باید خاصیت Active connection شی ء Command را به اتصال باز شده است کنید :
در این نقطه ، برای اجرای این فرمان و بازیابی داده ها ، دو روش وجود دارد. روش اول استفاده از روش Execute شی ء Command است که یک رکوردست بر می گرداند و می توانید آن را به یک شی ء Recordset نسبت دهید :
روش دوم اجرای یک فرمان این است که بگوییم این شی ء Command منبع داده یک Recordset است. در این ابتدا باید Recordset مزبور ایجاد شود :
حال باید دو متغیر از نوع Variant و با مقدار NULL ساخته و آن ها را به روش Open شی ء Recordset بدهیم. پارامتر سوم این روش نوع کرسر و پارامتر چهارم آن روش قفل کردن رکوردست است و بلاخره پارامتر پنجم روش Open پرچمیست که روش ارزیابی فرمان داده شده به پایگاه داده را مشخص می کند. در کد زیر روش کار را می بینید :
روش دیگری وجود دارد که می توانید بدان وسیله تمام اعمال را در چند خط کد انجام دهید. در این روش از دستورات Command و Connectionl مستقلا استفاده نمی کنیم ، و آن ها را در یک دستور Open شی ء Recordset قرار می دهیم. در این روش به جای دو پارامتر NULL از یک دستور SQL استفاده می کنیم :
نکته : با اینکه در برنامه های ساده مانند برنامه درس امروز ، استفاده از تابع Open شی ء Recordset ساده تر است ، اما اگر تعداد جستجوهای پایگاه داده زیاد شود بهتر است از همان روش قبلی استفاده کنیم.چون در آن صورت برای تمام دستورات SQL از یک اتصال پایگاه داده استفاده خواهیم کرد.
حرکت در Recordset
بعد ار بازیابی رکوردهای پایگاه داده و قرار دادن آن ها در یک شی ء Recordset ، باید بتوانیم در این رکوردست به این سو و آنسو برویم. همانطور که ممکن است حدس زده باشید برای این حرکات می توانیم از توابع MovePrevious ،Move Next وMove First استفاده کنیم. هیچ کدام از این توابع آرگومان نمی گیرند.
علاوه بر این توابع شی ء Recordset دارای دو خاصیت به نام های BOF و EOF ( که معمولا باید نام آن ها تغییر داده شود ) هم هست که رسیدن به مرز های رکوردست را نشان می دهند.
دسترسی به مقدار فیلد ها
جالب ترین قسمت کار با ADO هنگامیست که می توانیم با فیلد های پایگاه داده کار کنیم. همان طور که گفتم چون ADO باید بتواند با زبان های دستوری ، مانند VBScript یا Jscript ، کار کند فقط از نوع داده Variant استفاده می کند. این داده ها باید به نوعی که نیاز داریم تبدیل شوند. برای این کار دو روش وجود دارد. روش سر راستر آن است که مقادیر Variant را خوانده و سپس آن ها را به نوعی که می خواهیم تبدیل کنیم :
روش دیگر ، با آن که چندان سر راست نیست، بهتر است وکار با آن در نهایت ساده تر خواهد بود. میکروسافت برای تبدیل انواع داده تعدادی ماکرو تهیه کرده است. این ماکرو ها در یک کلاس قرار دارند و از آنها بصورت یک واسط استفاده خواهیم کرد. از کلاس CADORecordbidning مشتق شده و با دستور import# به برنامه ضمیمه می شود. این کلاس و ماکرو دارای توابع سازنده و مخرب نیست. هر فیل رکوردست دارای دو متغیر است یکی از نوع unsigned long که وضعیت فیلد را بر می گرداند و دومی خود متغیر فیلد می باشد. این دو متغیر باید از متغیر های معمولی C باشند و از کلاس های C++ ، مانند CString ، نمی توان برای این منظور استفاده کرد. به مثال زیر توجه کنید :
بعد از تعریف کلاس فوق که باید با فیلد های رکوردست همخوانی داشته باشد ، می توانیم از آن در برنامه خود استفاده کنیم :
بعد از یک اشاره گر به واسط iش می سازیم :
این متغیر به یک واسطه COM که بخشی از رکوردست ADO است اشاره می کند. بعد از بازیابی رکوردها باید اشاره گر واسط را استخراج کرده و رکوردست کلاسی که قبلا ساختیم را به شی ء RecordSet متصل کنیم :
حال دیگر برای دسترسی به مقدار هر فیلد کافیست از متغیر های عضو کلاس CcustmRs استفاده کنیم.
ماکروهای end-ADO-binding و begin-ADO-binding
ماکروهای تعریف شده در کلاس CcustomRs نقش کلیدی در دسترسی به فیلد های رکوردست دارند.
اولین این ماکروها ، BEGIN-AND-BINDING است که تنها یک پارامتر ( نام کلاس ) می گیرد. این ماکرو یک ساختار تعریف می کند که در سایر ماکروها از آن استفاده خواهد شد.
آخرین ماکروی کلاس فوق BEGIN-AND-BINDING نام دارد. این ماکرو ، که هیچ پارامتری نمی گیرد ، ساختار تعریف شده در اولین ماکرو را بر می چیند. کار واقعی کلاس CcustomRs در سایر ماکرو های آن صورت می گیرد.
ماکرو های ADO-FIXID-LENGTH-ENTRY
از این ماکرو ها برای فیلد هایی در پایگاه داده که طول آنها ثابت است استفاده کنیم ( فیلدهای تاریخ ، منطقی یا حتی متن های با طول ثابت). دو ویرایش از این ماکرو وجود دارد : ویرایش دوم ۲ ADO-FIXID-LENGTH-ENTRY نام دارد.
سه پارامتر اول و پارامتر آخر در هر دو ویرایش یکسان است. ویرایش اول به یک پارامتر اول نیاز دارد که در ویرایش دوم وجود ندارد. پارامتر اول شماره ترتیبی فیلد در رکوردست است. دستور SQL هم همین شماره را برگرداند. پارامتر دوم داده فیلد استک انواع داده موجود در فایل سرباره ای که دستور import# ساخته است تعریف شده اند. پارامتر سوم متغریست که مقدار فیلد در آن کپی خواهد شد. پارامتر چهارم ویرایش اول این ماکرو متغیر وضعیت فیلد است ( همان متغیر unsigned long که در کنار متغیر اصلی تعریف کردیم ). آخرین پارامتر یک ماکرو متغیر منطقی است که تعیین می کند که آیا فیلد قابل دستکاری هست یا خیر.
ماکرو های ADO_NUMERIC_ENTRY
از این ماکرو فقط برای فیلدهای عددی استفاده می شود. این ماکروها هم دو ویرایش دارد که در آخر انم دومی یک عدد دو اضافه شده است. دراین دو ویرایش هم پنج پارامتر اول و پارامتر آخر بکسان هستند و ویرایش اول یک پارامتر اضافی می گیرد که در ویرایش دوم وجود ندارند.
سه پارامتر اول و پارامتر آخر و ماقبل آخر ویرایش اول این ماکروها شبیه ماکروهای ADO_NUMERIC_ENTRY است. اما پارامتر های چهارم وپنچم این ماکرو ها منحصر به همین ماکرو ها هستند. پارامتر چهارم دقت مقدار فیلی را و پارامتر پنجم مقیاس آن را ، تعیین می کند. این دو پارامتر در تبدیل صحیح نوع Variant به مقادیر عددی نقش اساسی دارند.
ماکروهای ADO_VARIABLE_LENGTH_ENTRY
از این ماکرو ها برای فیلد های با طول متغیر استفاده می شود. در پایگاه داده ADO باید برای فیلد های VARCHAR از این ماکرو ها استفاده کند. این ماکرو سه ویرایش دارد. در هر سه ویرایش، چهار پارامتر اول و آخر یکسان هستند و پارامتر های بین آنها متفاوت است.
پارامتر اول شماره ترتیبی فیلدی است که دستور SQL ، برمی گرداند. پارامتر دوم نوع داده فیلد است. پارامتر سوم نوع داده ای است که مقدار فیلد در آن کپی می شود. پارامتر چهارم در تمام ویرایش های این ماکرو اندازه متغریست که مقدار فیلد در آن قرار داده خواهد شد. پارامتر آخر این ماکروها هم متغیر وضعیت فیلد است.
در ویرایش اول ، بین پارامتر چهارم و آخر دو پارامتر دیگر وجود دارد. در ویرایش دوم فقط اولی و در ویرایش سوم فقط دومی ظاهر خواهد شد. اولی ،یک متغیر وضعیت فیلد است. دومی ، هم اندازه این فیلد را مشخص می کند.
به روز در آوردن رکورد ها
به روز در آوردن رکورد های رکوردست بستگی به آن دارد که رکورد ها را با کدام روش بازیابی کرده اید. اگر همه فیلد ها را خودتان از نوع Variant به نوع مناسب تبدیل کرده اید ، باید تک تک فیلد ها را جدا گانه به روز در آید و مقدار جدید آن در کد ذیل روش کار را می بینید :
اگر کلاس رکورد را خودتان درست کرده باشید ، به روز در آوردن آن کمی ساده تر است. بعد از آنکه مقادیر جدید را به متغیر های کلاس دادید : می توانید با تابع update آن کلاس رکورد را به روز در آورید :
با این کار رکورد شی ء recordset با مقادیر جدید به روز در خواهد آمد.
اضافه وحذف کردن رکوردها
اضافه وحذف کردن رکورد ها به یک رکورد ست ADO شبیه سایر تکنولوژی های پایگاه داده است. با این حال تفاوت های ناچیزی هم در اضافه کردن رکورد جدید وجود دارد.
برای حذف رکورد فعلی می توانیم از روش DELETE شی ء recordset استفاده کنید ، این روش فقط یک آرگومان می گیرد که نحوه حذف رکورد را تعیین می کند. برای حذف رکورد فعلی می توانید از پارامتر (ADAFFECTCURRENT) استفاده کنید :
در اینجا هم چون بعد از حذف رکورد فعلی این رکورد دیگر وجود ندارد باید به رکورد قبلی ( یا بعدی ، هر طور که مایلید ) بروید.
برای اضافه کردن رکورد جدید باید از روش ADDNEW استفاده کنید. بعد از اضافه کردن رکورد جدید ، آن رکود به رکورد فعلی تبدیل خواهد شد ، اما تمام متغیرهای کلاس آن خالی هستند. قبل از آنکه کاربر بتواند در فیلدهای این رکورد چیزی وارد کند ، باید تمام متغیرهای کلاس آن را آماده کنیم ، این کار با دادن مقدار به متغیرهای کلاس رکورد انجام می شود و تمام این اعمال از طریق اشاره گر واسط رکورد صورت خواهد گرفت :
بدین ترتیب یک رکورد خالی خواهیم داشت که کاربر می تواند آن EDIT کند. بعد از آن کاربر مقادیر مورد نظر خود را در این رکورد وارد کرد، آنها به متغیرهای کلاس رکورد کپی می کنیم. و سپس با روش UPDATE رکورد را ذخیره می کنیم.
بستن اشیاء RECORDSET و CONNECTION
بعد از آنکه کارتان با رکوردست تمام شد باید آنرا ببندید:
و وقتی دیگر کاری با پایگاه داده نداشتید می توانید اتصال به پایگاه داده را هم ببندید:
برنامه پایگاه داده ADO
برنامه که امروز می نویسیم در واقع همان برنامه روز قبل است با این تفاوت که از تکنولوژی ADO برای کار با پایگاه داده استفاده می کنیم. در این برنامه هم کاربر تمام کارکرد های لازم از قبیل دستکاری رکورد ها و حذف یا اضافه کردن آنها را در اختیار خواهد داشت. همانطور که گفتم تکنولوژی ADO که امروز از آن استفاده خواهیم کرد در واقع یک لایه بر فراز دایور ODBC ( درس دیروز ) محسوب می شود.
ایجاد پوسته برنامه
برنامه امروز یک برنامه IDS است ولی هر کاری که در یک برنامه IDS بتوان انجام داد در برنامه های MDI و دیالوگی هم قابل انجام است. پس یک پروژه MFCAPPWIZARD بوجود آورید. نام پروژه را مثلاً ، DBADO بگذارید و در اولین صفحه با جادوگر برنامه نوع آن را SDI تعیین کنید. در مراحل دو تا پنج تنظیمات پیش فرض را قبول کنید در مرحله دوم گزینه عدم پشتیبانی از پایگاه داده را به حال خود رها کنید! در آخرین مرحله جادوگر برنامه تصریح کنید که کلاس نما باید از کلاس CFORMVIEW مشتق شود.
بعد از ایجاد پوسته برنامه، باید فرم اصلی آنرا طراحی کنیم. مانند روز قبل برای فیلد های جدول ADDRESSES کنترل های لازم را روی دیالوگ برنامه قرار دهید ( به شکل ۱‑۴ نگاه کنید ). برای تنظیم خواص کنترل های برنامه می توانید از جدول ۱۵-۱ استفاده کنید.
نکته : اگر وقت زیادی برای طراحی فرم برنامه ندارید، فقط کافی است فیلد های اصلی پایگاه داده را روی آن قرار دهید.
بعد از قرار دادن کنترل ها روی دیالوگ برنامه ، باید در جادوگر کلاس برای تمام آنها متغیر تعریف کنید، برای این کار از جدول ۱‑۱ ، استفاده کنید. نوع این متغیر ها باید با فیلدهای پایگاه داده ای که با آن سروکار دارید مطابقت داشته باشند.
جدول ۱‑۱ : خواص کنترل های برنامه
مقدار | خاصیت | شی |
BIRTHDATE | CAPTION | |
IDC-EDIT- BIRTHDATE | ID | EDIT BOX |
IDC-STATIC | ID | STATICTEXT |
SEND CARD | CAPTION | |
IDC-CHECK- SEND CARD | ID | CHECK BOX |
IDC-STATIC | ID | STATIC TEXT |
NOTES | CAPTION | |
IDC-EDIT-NOTES | ID | EDIT BOX |
ایجاد کلاس رکورد
قبل از آنکه در نوشتن برنامه جلوتر بروید، باید کلاسی را که به رکوردست متصل خواهد شد ایجاد کنیم. در این کلاس برای هر فیلد در جدول پایگاه داده به یک متغیر PUBLIC ( و یک متغیر وضعیت ) نیاز داریم. برای تبادل داده ها بین متغیرهای کلاس و فیلدهای رکوردست هم به تعدادی ماکرو ، نیاز خواهیم داشت. پس ، با همان روش روز قبل یک کلاس GENERIC بسازید. این کلاس ، مثلآ ، CCOSTOMRS نام دارد یک کلاس UBLIC است و از کلاس CADORECORDBINDING به عنوان کلاس مبنا استفاده می کند.
بعد از ایجاد شدن این کلاس ، توابع سازنده و مخرب را از فایل های منبع و سرباره حذف کنید. در فایل سرباره کلاس جدید فایل ADODLL را به این کلاس وارد کرده و متغیر ها و ماکرو های لازم را هم در آن تعریف کنید ( به لیست ۱-۱۵ نگاه کنید ).
سپس باید در کلاس سند یک متغیر از این کلاس تعریف کنید. این متغیر که M-RSRECSET نام خواهد داشت از نوع CCOSTOMRS است و دسترسی PRIVATE دارد. کلاس رکورد را باید به فایل سرباره کلاس سند هم اضافه کنید، به لیست ۱‑۱ ، نگاه کنید.
لیست ۱‑۱ : ضمیمه کردن کلاس رکورد به کلاس سند
نکته دیگری که باید به آن توجه کنیم، استخراج یک اشاره گر به کلاس رکورد از کلاس سند است. این تابع باید یک اشاره گر به متغیر کلاس رکورد را برگرداند. پس یک تابع عضو به نام GETRECSET از نوع CCOSTOMRS و با دسترسی PUBLIC ایجاد کرده و کد لیست ۱‑۲ را در آن بنویسید.
قبل از پرداختن به برنامه نویسی ADO باید یک تابع دیگر برای گزارش خطاهایADO و پایگاه داده بنویسیم. این تابع علاوه بر کد خطا پیام آن را هم به کاربر نشان خواهد.
بنابراین ، تابع عضو جدیدی بنام ( GENERALERROR ESULTHR,PWSTRPWSZEDESCRIPTION ) از نوع VOID و با دسترسی PUBLIC ایجاد کرده و کد لیست ۱‑۳ ، را در آن بنویسید.
لیست ۱‑۳ : تابع GENERATEERROR
اتصال به پایگاه داده و بازیابی داده ها
برای اتصال به پایگاه داده و بازیابی رکوردهای آن از تابع ONNEWDOCUMENT استفاده خواهیم کرد. اما قبل از آن باید چند متغیر را در کلاس سند تعریف کنیم که عبارتند از یک اشاره گر به شی ء RECORDSET یک اشاره گر به واسط IADORECORDBINDING و دو متغیر رشته ای برای نگهداری رشته اتصال پایگاه داده و فرمان SQL ، برای تعریف این متغیر ها از جدول ۱‑۲ ، استفاده کنید.
جدول ۱‑۲ : متغیر های عضو کلاس سند
دسترسی | نوع | نام |
PRIVATE | RECORDSET_ | M_PRS |
PRIVATE | IADORECORDBINDING* | M_PIADORECORDBINDING |
PRIVATE | CSTRING | M_STRCONNECTION |
PRIVATE | CSTRING | M_STRCMDTEXT |
برای دسترسی به پایگاه داده در تابع ONNEWDOCUMENT باید مراحلی را طی کنیم : ابتدا باید رشته اتصال پایگاه داده و دستور SQL مورد نیاز را تهیه کنیم. سپس باید محیط COM را با دو اشاره گر NULL آماده کار کنیم. برای ایجاد شی ء RECORDSET از تابع CREATEINSTANCE استفاده خواهیم کرد. باز کردن RECORDSET ، اتصال به پایگاه داده و اجرای دستور SQL همزمان انجام خواهد شد. سپس کلاس رکورد را با اشاره گر واسط IADORECORDBINDING به رکوردست متصل می کنیم. در پایان هم به کلاس نما می گوییم که کنترل ها را به روز در آورد و رکورد اول را نمایش دهد ( البته با کمک تابعی که خواهیم نوشت )، کد لیست ۱۵-۵ تابع IADORECORDBINDING را نمایش می دهد.
قبل از از ادامه کار ،کد لازم برای بستن صحیح برنامه را می نویسیم. در این کد رکوردست بسته شده و اشاره گر واسط اتصال به کلاس رکورد از بین برده می شود. محیط COM هم باید بسته شود. برای این عملیات از روال رویداد DELETECONTENTS کلاس سند استفاده خواهیم کرد. لیست ۱‑۴ ، روش کار را نشان می دهد.
لیست ۱‑۴ : تابع DELETECONTENTS
پر کردن کنترل های فرم
۱:VOID CDBADODOC::DELETECONTECONTENTS()
۲:{
۳: //TODO: ADO YOUR SPECIALIZED COD HEAR AND/OR CALL THE BASE CLASS
۴: //CLOSE THE RECORD SET
۵: IF(M_PRS)
۶: M_PRS->CLOSE()
۷: //DO WE HAVE A VOID POINTER TO THE RECORD BINDING?
۸: IF(M_ PIADORECORDBINDING)
۹: //RELEASE IT
۱۰: M_ PIADORECORDBINDING->RELEASE():
۱۱: //SET THE RECORD SET POINTER TO NULL
۱۲: M-PRS=NULL:
۱۳:
۱۴: //SHUT DOWN THE COM ENVIRONMENT
۱۵: COUNINTIALIZE():
۱۶:
۱۷: CDOCUMENT::DELETECONTENTS():
۱۸:}
برای نمایش فیلدهای رکوردست ، تابعی مینویسیم تا فیلدهای هر رکورد را از کلاس رکورد به متغیر های کلاس نما کپی کند. سپس ، وضعیت هر فیلد را چک می کند و اگر وضعیت مناسب باشد مقدار فیلد را در متغیر مربوطه کپی میکند. بعد از کپی شدن تمام فیلدها، باتابع UPDATEDATA کنترل ها را به نمایش آنها وا میداریم. پس ، تابع جدیدی بنام REFRESHNOUNDDATA ( در کلاس نما ) از نوع VOID و با دسترسی PUBLIC ساخته و کد لیست ۱۵-۷ را در آن بنویسید.
تهیه: چون مستقیمآ با کلاس رکورد کار می کنیم باید کلاس رکورد را مانند کلاس سند به فایل سرباره کلاس نما هم ضمیمه کنیم.
ذخیره کردن تغییرات
برای ذخیره کردن تغییراتی که کاربر در فیلدهای یک رکورد می دهد، باید فرآیند فوق را معکوس کنیم. برای آنکه مطمئن شویم هر تغییری ذخیره می شود تمام فیلدها را بدون استثناء کپی خواهیم کرد. بنابراین ، تابع جدیدی بنام UPDATEBOUNDDATA ( در کلاس نما ) از نوع VOID و با دسترسی PRIVATE ایجاد کرده و کد لیست ۱۵-۸ را در آن بنویسید.
حرکت رکوردست
برای حرکت رکوردست به چهار منوی PREVIOUSE,LAST,FIRST و NEXT نیاز داریم. چون شی ء RECORDSET و اشاره گر های واسط در کلاس سند قرار دارند ، رویداد این منوها باید به این کلاس فرستاده شود تا بعد از به روز در آوردن رکورد فعلی حرکت به رکورد مورد نظر انجام شود. اما، کلاس نما هم به این رویدادها نیاز دارد.
چون باید بتواند کنترل ها را به روز در آورد. بعد از رفتن به رکورد جدید هم از این نما باید بتواند مقدار فیلدهای آن را نمایش دهد. با کمی دقت متوجه خواهید شد که بهتر است روال رویدادهای منو در کلاس نما قرار گیرد ( و از آنجا به کلاس سند هم فرستاده شوند ).
بنابراین ، چهار منو ( و چهار دکمه میله ابزار ) برای حرکات مورد نظر بسازید. در کلاس نما برای رویداد COMMAND هر چهار آیتم تابع مناسب را ساخته و کد لیست ۱‑۵ ، را در تابع روال منوی MOVE FIRST بنویسید.
حال باید تابع MOVE FIRST را در کلاس سند بنویسیم تا حرکت به رکورد اول انجام شود. برای این کار تابع جدیدی به نام MOVE FIRST ( با مقدار برگشتی VOID و با دسترسی PUBLIC ) در کلاس سند ایجاد کرده و کد لیست ۱‑۶ ، را در آن بنویسید.
لیست ۱‑۶ : تابع Move First
برای توابع MOVE LAST,MOVE PREVIOUSE و MOVE NEXT هم به کد مشابهی در روال های مربوطه ( در کلاس سند و کلاس نما ) نیاز داریم. بعد از نوشتن این توابع ، می توانید برنامه را کامپایل و اجرا کنید. شکل ۱‑۳ ، اجرای برنامه را در این مرحله نشان می دهد. تا اینجا فقط می توانید رکورد ها را مشاهده کرده و آنها را دستکاری کنید.
اضافه کردن رکورد جدید
حال که می توانید در رکورد های رکوردست به این سو وآنسو برویم، خوب است که توانایی اضافه کردن رکورد های جدید را هم به برنامه اضافه کنیم. روش کار درست مثل روش حرکت در میان رکورد هاست: یک آیتم جدید منو، تحریک رویداد آن ، نوشتن مقدار فیلدها در رکوردست ، فراخوانی تابع کلاس سند و به روز درآوردن رکورد فعلی ، تا آنجا که به کلاس تابع مربوط می شود ، تنها فرقی که این تابع با توابع قبلی دارد ID منو و نام تابع است ، تفاوت عمده در کلاس سند است.
در تابع کلاس سند ، بعد از به روز در آوردن رکورد فعلی ،یک رکورد خالی ایجاد کرده و آن را به رکوردست اضافه می کنیم و چون این رکورد آخرین رکورد است باید بلافاصله تابع MOVELAST را اجرا کنیم. بعد از آن باید اجازه دهیم تا کلاس نما این رکورد خالی را نمایش دهد.
برای این منظور ، یک آیتم جدید به منوی DATA اضافه کرده و تابعی برای رویداد COMMAND آن ( در کلاس نما ) ایجاد کنید. برای این تابع از همان کد لیست ۱‑۵ ، استفاده کرده و فقط در آن از روش ADDNEW استفاده کنید. حال در کلاس سند ، تابعی به نام ADDNEW ( با مقدار برشتی VOID و دسترسی PUBLIC ) ساخته و کد لیست ۱۵-۱۱ را در آن بنویسید.
در تابع ADDNEW از تابعی بنام createblankrecord استفاده کرده ایم که اینک آن را می نویسیم، این تابع به تمام فیلدهای رکورد جدید یک رشته خالی نسبت می دهد. پس، تابع جدیدی بنام createblankrecord ( با مقدار برگشتی void و دسترسی private ) در کلاس سند و کد لیست ۱۵-۱۲ را در آن بنویسید.
اگر برنامه را کامپایل و اجرا کنید ، خواهید دید که می توانید رکوردهای جدیدی به پایگاه داده اضافه کرده و آن ها را ویرایش کنید.
حذف کردن رکورد ها
آخرین قابلیتی که به برنامه امروز اضافه خواهیم کرد امکان حذف رکوردهاست. روش کار دقیقآ مانند قبل است یعنی شامل ایجاد آیتم جدید در منوی data ، تحریک رویداد آن، به روز در آوردن رکورد فعلی، فراخوانی تابع مربوطه در کلاس سند و سپس به روز در آوردن فرم برنامه ، می باشد.
تابع حذف رکورد در کلاس سند دقیقا شبیه همان تابع اضافه کردن رکورد است با این تفاوت که از روش delete استفاده خواهد کرد و بعد از حذف رکورد به رکورد قبلی خواهد رفت.
برای پیاده سازی این قابلیت، آیتم جدیدی به منوی data اضافه کرده و در تابع رویداد Command آن کد لیست ۱‑۵ ، را بنویسید و در آن فقط از تابع delete کلاس سند استفاده کنید. سپس تابعی بنام delet ( با مقدار برگشتی void و دسترسی private ) در کلاس سند ساخته و کد لیست ۱۵-۱۳ را در آن بنویسید.
بازیابی داده ها از پایگاه داده ODBC
برنامه های زیادی از پایگاه داده استفاده می کنند. طیف وسیعی از برنامه های ساده مدیریت اطلاعات شخصی تا سیستم های پیچیده و بزرگ بانکی و حقوقی برای ذخیره و پردازش اطلاعات از پایگاه داده استفاده می کنند. برای کار با پایگاه داده چهار تکنولوژی مختلف عرضه می کند:
در این بحث یاد می گیریم که :
چگونه می توانید با ODBC، بدون نگرانی از عدم سازگاری درونی پایگاه داده ، کار کنید. چگونه با استفاده از کلاس CRECORDSET با داده های منبع ODBC کار می کند.
چگونه با جادوگرهای می توان یک برنامه ساده پایگاه داده ساخت.
و چگونه می توان در برنامه های رکورد های یک پایگاه داده ODBC را حذف یا اضافه کرد.
دسترسی به پایگاه داده و ODBC
تمام برنامه ها به نحوی از انحنا با داده سر و کار دارند. این داده ها معمولآ در یک پایگاه داده و به صورت رکورد (RCORD) سازماندهی می شوند. اگر یک برنامه حرفه ای می نویسید به احتمال زیاد با پایگاههای داده سرو کار پیدا خواهید کرد. اما سوال اینست که ، با کدام پایگاه داده سرو کار خواهید داشت ؟
امروزه در بازار نرم افزار تعداد زیادی برنامه پایگاه داده وجود دارد. اگر می خواهید برنامه ای تک کاربره که فقط روی یک کامپیوتر اجرا شود بنویسید ، می توانید از هر یک از پایگاههای داده موجود در بازار ، از قبیل اکسس[۲۰] ، فاکس پرو[۲۱] یا پارادوکس[۲۲] ، استفاده کنید اما اگر برنامه ای که می نویسید باید با پایگاههای داده بزرگ و با اشتراک گذاشته شده کار کند احتمالا باید از یکی از پایگاههای داده سازگار با [۲۳]SQL ، مانند اوراکل[۲۴] یا SQL SERVCR استفاده کند. تمام این پایگاههای داده رفتار تقریبآ مشابهی دارند و به رکورد بعنوان عنصر اطلاعاتی متکی هستند آنها اجازه می دهند تا به پایگاه داده رکورد اضافی کنید ، رکورد ها را حفظ کرده و یا آنها را دستکاری کنید. از هر یک از این پایگاههای داده می توانید در برنامه های خود استفاده کنید و در برنامه بعدی سراغ پایگاه داده دیگری بروید.
مشکل رفتن از یک پایگاه داده به پایگاه داده دیگر این است که هر کدام روش متفاوتی برای دسترسی به داده ها دارند و هر بار باید زبان جدید و توابع متفاوتی را یاد گرفته و مورد استفاده قرار دهید و این همان مشکلی است که ODBC برای رفع آن اختراع شده است.
واسط ODBC
دیدید که هر پایگاه داده دارای واسط خاص خود است ( به احتمال زیاد ) با پایگاههای داده دیگر سازگاری ندارد و این نکته ای بود که میکرو سافت هم آن را دریافته بود. این مشکلی بود فراروی تمام برنامه نویسان و کار آن ها را در استفاده از انواع مختلف پایگاه داده پیچیده می کرد ، چون آنها نمی توانستند از آموخته هایشان در زمینه کار با یک نرم افزار در نرم افزارهای دیگر استفاده کنند. بزودی نیاز به یک زبان استاندارد برای کار با تمام انواع پایگاه داده به یک ضرورت تام تبدیل شد.
واسط ODBC ( رابط پایگاه داده باز[۲۵] ) یک واسط استاندارد بر اساس زبان SQL است که با سیستم عامل ویندوز هم یکپارچه شده است. ورای این واسط هر پایگاه داده برای خود درایو هایی دارد که توابع ODBC بومی هر پایگاه داده تبدیل می کند. واسط ODBC دارای مجموعه ای استاندارد از پیکر بندی های لازم برای کار با پایگاه داده هم هست. با این پیکر بندی ، برنامه نویسان دیگر نیازی به یادگیری واسط های مختلف برای کار با انواع پایگاه داده ندارند و تولید کنندگان نرم افزار هم می توانند با افزودن واسط ODBC به برنامه های خود یک دسترسی شفاف و استاندارد برای محصول خود داشته باشند.
کلاس CRECORDSET
قسمت اعظم واسط ODBC در محیط در دو کلاس CRECORDSET و CDATABASE قرار دارد. کلاس CDATABASE حاوی اطلاعات لازم برای ارتباط با پایگاه داده است و می تواند در تمام برنامه به اشتراک گذاشته شود. کلاس CRECORDSET مجموعه ایست از چند رکورد یک پایگاه داده به کمک کلاس CRECORDSET می توانید یک جستجوی (SQL QUERY) SQL اجرا کرده و رکورد هایی را که با این جستجو مطابقت دارند در اختیار داشته باشید با این کلاس می توانید رکورد ها را دستکاری کرده و آنها را مجدداً در پایگاه داده ذخیره کنید و حتی می توانید رکوردهایی را به پایگاه داده اضافه و یا از آن حذف کنید.
اتصال به پایگاه داده
قبل از آن که کلاس CRECORDSE بتواند کاری انجام دهد ، باید به پایگاه داده متصل[۲۶] شده باشد. این کار از طریق کلاس CDATABASE صورت می گیرد البته شما خود نیازی به ایجاد شی CDATABASE ندارید چون اولین شی کلاس CRECORDSET اینکار را برایتان انجام خواهد داد. وقتی با جادوگر برنامه یک برنامه ODBC می سازید خود جادوگر اطلاعات مربوط به اتصال پایگاه داده را در کلاسی که از CRECORDSET مشتق می کند قرار خواهد داد وقتی این کلاس شی CDATABASE را دریافت می کند از اطلاعات پیش فرض جادوگر برنامه برای اتصال به پایگاه داده استفاده خواهد کرد.
بازکردن و بستن رکوردست
بعد از ایجاد شی CRECORDSET و اتصال ان به پایگاه داده برای دستیابی به رکوردهای درون آن باید رکوردست (مجموعه رکوردهای پایگاه داده ) را باز کنید.
برای این کار باید از تابع OPEN که عضو کلاس CRECORDSET است استفاده کنید.
اگر مقادیر پیش فرض این تابع نیازتان را بر آورده می کند می توانید آن را بدون هیچ آرگومانی فراخانی کنید.
اولین آرگومان تابع OPEN نوع رکوردست است مقدار پیش فرض این آرگومان یعنی TYPE-DEFAULT-USE-DB-AFX رکوردست را به صورت یک اسناپ شات[۲۷] باز می کند.
چهار نوع رکوردست وجود دارد که آنها را در جدول ۱‑۳ ، می بینید اما جادوگر برنامه فقط دو نوع از آنها را در اختیار شما می گذارد.
نوع | مفهوم |
Crecordset::dynaset | مجموعه ای از رکوردها که می توان آنها با تابع Fetch به روز در آورد و تغییرات رکوردها را مشاهده کرد. |
Crecordset::snapshot | مجموعه ای از رکوردها که بدون باز و بستن کردن دوباره رکوردست ، نمی توان آن را به روز در آورد. |
Crecordset::dynamic | شبیه نوع dynaset با این تفاوت که بسیاری از درایو های ODBC از آن پشتیبانی نمی کند. |
Crecordset::forwardonly | یک رکوردست فقط خواندنی که فقط می توان آن را از اول تا آخر مشاهده کرد. |
آرگومان دوم تابع OPEN دستور SQR استخراج رکوردست است اگر این آرگومان NULL باشد از دستور SQL پیش فرض (که جادوگر برنامه بوجود آورده ) استفاده خواهد شد.
آرگومان سوم تعدادی پرچم است که نحوه بازیابی رکوردهای رکوردست را تعیین خواهد کرد اکثر این پرچم ها به دانش عمیقی از ODBC و طرز کار آنها نیاز دارند. در جدول ۱‑۴ ، تعدادی از این پرچم ها را می بینید.
جدول ۱‑۴ : پرچم های باز کردن رکوردست.
پرچم | مفهوم | |
CRECORDSET::NONE | مقدار پیش فرض این آرگومان باز شدن رکوردست تحت تاثیر هیچگونه ای نخواهد بود. | |
CRECORDSET::appendoly | با این پرچم کاربر قادر به حذف یا دستکاری رکورد های رکوردست نخواهد بود و فقط می تواند رکورد هایی را به آن اضافه کند. از این پرچم نباید همزمان با پرچم CRECORDSET::appendoly استفاده کرد. | |
CRECORDSET::reADOnly | با این پرچم رکوردست فقط خواندنی خواهد بود و هیچ تغییری در آن مجاز نیست. از این پرچم نباید همزمان با CRECORDSET::appendonly استفاده کرد. |
بعد از آن که کار تان با رکوردست تمام شد می توانید با تابع CLOSE آن را بسته و منابع سیستم را آزاد کنید تابع CLOSE هیچ آرگومانی نمی گیرد.
حرکت دو رکوردست
بعد از بازیابی رکوردست دلخواه از پایگاه داده باید بتوانید در آن به اینسو و آنسو بروید (مگر آن که رکوردست شما فقط یک رکورد داشته باشد ). توابع زیادی برای حرکت در رکوردست در کلاس Crecordset وجود دارد که با کمک آنها می توانید به هر رکوردی که میل دارید بروید این توابع را در جدول ۱‑۵ ، می بینید.
جدول ۱‑۵ : توابع حرکت در رکوردست
تابع | مفهوم |
Movefirs | رفتن به اولین رکورد در رکوردست. |
Movelast | رفتن به آخرین رکورد در رکوردست. |
Movenext | رفتن به بعدیاولین رکورد در رکوردست. |
Moveprev | رفتن به قبلی رکورد در رکوردست. |
Move | رفتن به رکورد دلخواه در رکورد فعلی یا اولین رکورد رکورد است. |
Setabsoluteposition | رفتن به رکورد دلخواه در رکوردست |
Isbof | اگر رکورد فعلی آخرین رکورد رکوردست باشد true بر می گرداند. |
getrecordcordcount | تعداد رکورد های رکوردست را بر می گرداند. |
از تمام این توابع فقط دو تای آن ها ( MOVE و SETAbsolutePOSITION ) آرگومان می گیرند تابع SETAbsolutePOSITION یک آرگومان می گیرد و آن شماره رکوردیست که می خواهیم به آن برویم مقدار O ما را به ابتدای فایل (BOF) می برد در حالی که I اولین رکورد رکوردست است اگر به این آرگومان مقدار منفی بدهیم شمارش از آخرین رکوردور و به عقب انجام خواهد شد : ١ - آخرین رکورد است ٢ -رکورد ماقبل آخر و....
تابع MOVE دو آرگومان میگیرد : آرگومان اول شماره رکورد (سطر) مورد نظر است. این عدد میتواند مثبت یا مفی باشد ،که اعداد منفی باعث حرکت رو به عقب خواهند شد. آرگومان دوم روش حرکت در رکوردست را تعیین خواهد کرد. در جدول ۱‑۶ ، مقادیر ممکنه این آرگومان را مشاهده می کنید.
گزینه | مفهوم |
SQL-FETCH-RELATIVE | رفتن به رکورد مشخص شده از رکورد فعلی. |
SQL-FETCH-NEXT | رفتن به رکورد بعدی بدون توجه به عدد داده شده همان ( MOVENEXT ) است. |
SQL-FETCHPRIOR | رفتن به رکورد قبلی بدون توجه به عدد داده شده همان ( MOVEPREV ) است. |
SQL-FETCHFIRT | رفتن به اولین رکورد بدون توجه به عدد داده شده همان ( MOVELAST ) است |
SQL-FETCHABSOLUTE | رفتن به رکورد مشخص شده از ابتدای رکوردست همان ( SETABSOLUTEPOSTION ) است. |
اضافه کردن حذف کردن و به روز در آوردن رکوردها
حرکت در رکوردست فقط بخشی از آن چیزیست که به آن نیاز داریم. ما باید قادر به اضافه یا حذف کردن رکوردها و به روز در آوردن آنها هم باشیم. برای این اعمال هم توابعی در کلاس CRECORDSET وجود دارد که آنها را در جدول ۱‑۷ ، میبینید.
جدول ۱‑۷ : توابع EDIT کردن رکوردست
تابع | مفهوم |
ADDNEWW | یک رکورد جدید به رکوردست اضافه می کند. |
DELETE | رکورد فعلی را از رکوردست حذف می کند. |
EDIT | اجازه ادیت کردن رکورد فعلی را می دهد. |
UPDATE | تغییرات را در پایگاه داده ذخیره می کند. |
REQUERY | برای به روز درآوردن رکوردست دستور SQL فعلی را دو بار اجرا می کند. |
هیچ یک از این توابع آرگومان نمی گیرند ولی برای کار با برخی از آنها اجرای مقدماتی لازمست. مثلا بعد از اضافه کردن یک رکورد جدید با تابع ADDNEW ، باید مقدار پیش فرض فیلد کلیدی (key field) ان را ست کنید و سپس با تابع Update تغییرات رادر پایگاه داده ذخیره کنید ٠ اگر قبل از اجرای تابع Update به رکورد دیگری بروید رکورد جدید از بین خواهد رفت. بعد از ذخیره کردن رکورد جدید ، بایستی با تابع Requrecy رکوردست را به روز درآورید تا کاربر بتواند رکورد جدید را Edit کند. در قطعه کد ذیل این فرآیند را مشاهده می کنید :
برای حذف رکورد فعلی کافیست تابع delete را اجرا کنید ولی بعد از حذف این رکورد باید به رکورد دیگری بروید تا کاربر دیگر رکورد حذف شده را نبیند ( بعد از حذف رکورد فعلی دیگر این رکورد وجود ندارد و باید بلافاصله به رکورد دیگری بروید ) برای اینکار نیازی به اجرای صریح تابع update ندارید.
قطعه کد ذیل روش حذف رکورد فعلی را نشان می دهد :
قبل از آن که کاربر بتواند رکورد فعلی EDIT کند باید تابع EDIT را اجرا کرده باشید بدین ترتیب می توان فیلد های رکورد EDIT کرد بعد از انجام تغییرات ، باید با آن ها را تابع Update در پایگاه داده ذخیره کنید :
شاید فکر کنید که چگونه می توان فیلد های یک رکورد EDIT کرد. وقتی جادوگر برنامه کلاس مشتق از Crecordset را می سازد به هر فیلد یک متغیر عضو نسبت می دهد که می توان به کمک آن فیلد ها را EDIT کرد.
ایجاد برنامه پایگاه داده با استفاده از ODBC
برنامه ای که امروز می نویسیم یک برنامه SDI با پشتیبانی ODBC است. این برنامه رکورد ها را از یک پایگاه داده ODBC استخراج کرده و به کاربر اجازه ویرایش آنها را می دهد. برنامه ما قادر به حذف رکوردها و یا اضافه کردن رکوردهای جدید نیز خواهد بود.
آماده کردن پایگاه داده
قبل از نوشتن برنامه باید پایگاه داده ای داشته باشیم که بتوانیم از آن در برنامه استفاده کنیم. تقریبآ تمام نرم افزارهای پایگاه داده دارای ابزارهایی برای ایجاد پایگاه داده جدید هستند. با استفاده از این ابزارها یک پایگاه داده بسازید و سپس به کمک مدیر ODBC (ODBC Adimnistrator ) برای آن یک منبع ODBC تهیه کنید.
در برنامه ای که امروز می نویسیم از یک پایگاه داده استفاده شده است این پایگاه داده بر اساس مدل Address Book ساخته شده و در آن از فیلد ها و گزینه های پیش فرض جادوگر پایگاه داده Access استفاده شده است. به شکل ۱۴-۱ نگاه کنید بعد از ایجاد پایگاه داده باید برای ارتباط با آن یک منبع ODBC بسازیم. برای این منظور از مدیر ODBC روی Add کلیک کنید ( شکل ۱۴-۲ (تا دیالوگ انتخاب درایور منبع ODBC ( شکل ۱۴-۳ ) باز شود چون پایگاه داده ای که در مرحله قبل ساخته ایم از نوع Access است آیتم Microsoft access را انتخاب کرده و دکمه Finish را کلیک کنید در دیالوگ بعدی ، ODBC Micrisoft access setup ( شکل ۱۴-۴ ( باید یک نام ساده به منبع داده خود بدهید. برنامه از این نام برای پیکر بندی منبع ODBC و اتصال به آن استفاده خواهد کرد بنابراین باید به اندازه کافی گویا و در عین حال ساده باشد. نامی که برای برنامه امروز انتخاب شده TYVCDB است در فیلد بعدی هم توضیحی درباره پایگاه داده وارد کنید.
شکل ۱‑۶ :
شکل ۱‑۷
بعد از وارد کردن نام و توضیح منبع داده باید محل آن را تعیین کنید. با کلیک کردن دکمه Select پایگاه داده ای را که ساخته اید انتخاب کنید بعد از آن روی OK کللیک کنید تا کار ایجاد منبع داده ODBC به پایان برسد مدیر ODBC را هم ببندید.
شکل ۱‑۸
ایجاد پوسته برنامه
همانطور که گفتیم برنامه امروز یک برنامه SDI استاندارد با پشتیبانی پایگاه داده است پروژه جدیدی از نوع Appwizard ایجاد کرده و نام آن را مثلآ Database بگذارید. در اولین صفحه جادوگر برنامه نوع آن را SDI انتخاب کنید در صفحه دوم گزینه Database view با پشتیبانی فایل را انتخاب کنید. روی دکمه Data Souree کلیک کرده و منبع داده ای را که در قسمت قبل ساختید به آن معرفی کنید به دیالوگ گزینه های پایگاه داده ( شکل ۱۴-۵ ) نگاه کنید نوع رکوردست را هم می توانید در همین دیالوگ تعیین کنید. وقتی OK را کلیک کنید دیالوگ دیگری ظاهر خواهد شد که در آن می توانید جدول[۲۸] های موجود در این پایگاه داده را انتخاب کنید.
در سایر مراحل جاوگر برنامه گزینه های پیش فرض را قبول کنید تا به آخرین مرحله آن برسید در این مرحله خواهید دید که جادوگر برنامه کلاس جدیدی به برنامه اضافه کرده است اگر این کلاس را انتخاب کنید متوجه می شوید که از کلاس Crecordset مشتق شده است. همچنین متوجه خواهید شد که کلاس نمای برنامه که از کلاس Crecordset view مشتق شده زیر کلاس Cform view است.
بعد از ایجاد پوسته برنامه باید فرم اصلی آن را که محل مشاهده ویرایش کردن رکوردهای پایگاه داده است ، طراحی کنید این فرم را با استفاده از کنترل های استاندارد طراحی خواهیم کرد شکل ۱‑۹ و جدول ۱‑۸ شما را در این راه راهنمایی خواهند کرد.
نکته : اگر وقت زیادی برای طراحی فرم برنامه ندارید کافیست فقط فیلد های اصلی پایگاه داده ( send card – birthdate – last name – first name – id ) را روی آن قرار دهید.
جدول ۱‑۸ : خواص کنترلهای برنامه پایگاه داده
مقدار | خاصیت | شی ء | مقدار | خاصیت | شی ء | مقدار | خاصیت | شی ء |
ESNAME | ID | STATIC TEXT | IDC- | ID | STATIC TEXT | |||
ID | STATIC TEXT | IDC-STATIC: | STATEC: | |||||
IDC-STATIC: | CAPTION | ID: | CAPTION | |||||
CAPTION | LAST NAME: | ID | EDIT BOX | |||||
ADDRESS: | ID | EDIT BOX | ID-EID: | |||||
ID | EDIT BOX | IDC-ELNAME: | ID | STATIC TEXT | ||||
IDC-EADDR : | ID | STATIC TEXT | IDC-STATIC | |||||
MULTILINE | IDC-STATIC: | CAPTION | ||||||
CHECKED | CAPTION | FIRST NAME: | ||||||
ID | STSTICTEXT | SPUSE NAME: | ID | EDIT BOX | ||||
IDC-STATIC: | IDC- | ID | EDIT BOX | IDC-EFNAME: | ||||
CAPTION | IDC-EZIP: | IDC-STATIC: | ||||||
CITY: | ID | STATIC TEXT | CAPTION | |||||
ID | EDIT BOX | STATIC TEXT | STATE | |||||
IDC-ECITY: | CAPTION | ID | EDIT BOX | |||||
ID | STATIC TEXT | COUNTRY: | IDC-ESTATIC: | |||||
E-MAIL: | IDC- | ID | EDIT BOX | ID | STATIC TEXT | |||
ID | EDIT BOX | ECOUNTRE: | IDC-STATIC: | |||||
IDC-EEMAIL: | ID | STATIC TEXT | CAPTION | |||||
ID | STATIC TEXT | IDC-STATIC: | ZIP: | |||||
IDC-STATIC: | CAPTION | ID | EDIT BOX | |||||
CAPTION | SEND CARD | EXTENSION: | ||||||
HOME PHONE: | ID | STATIC TEXT | ID | EDIT BOX | ||||
IDC- | ID | EDIT BOX | IDC-STATIC: | IDC-EWEXT: | ||||
EHPHONE: | CAPTION | ID | STATIC TEXT | |||||
ID | STATIC TEXT | NOTES: | IDC-STATIC: | |||||
IDC-STATIC: | ID | SDIT BOX | CAPTION | |||||
CAPTION | IDC-ENOTES: | FAX: | ||||||
WORK PHON: | MULTILINE | ID | EDIT BOX | |||||
IDC- | ID | EDIT BOX | CHECKED | IDC-EFAX: | ||||
EWPHONE: | IDC-EDOB: | ID | CLEEK TEXT | |||||
IDC- | ID | STATIC TEXT | ID | CHECK BOX | IDC-STATIC: | |||
IDC-STATIC: | IDC-CBCARD: | CAPTION | ||||||
CAPTION | CAPTION | BIRTHDATE: | ||||||
ID | EDIT BOX |
بعد از طراحی فرم برنامه ، نوبت به برقراری پیوند بین کنترلها و فیلدهای پایگاه داده می رسد اگر در جادوگر کلاس به برگه MEMDER VARIADLE بروید و یک کنترل را انتخاب کرده و برای آن متغیر تعریف کنید خواهید دید که دیالوگ اضافه کردن متغیر عضو در محل نام متغیر دارای یک جعبه ترکیبی بازشو است. اگر این لیست را باز کنید در ان تمام فیلدهای پایگاه داده را خواهید دید بدین ترتیب قادر خواهید بود تا هر کنترل را به یکی از فیلد های پایگاه داده مرتبط کنید. با توجه به جدول ۱‑۹، برای هر کنترل فیلد مناسب را انتخاب کنید.
نام | شی ء |
M-PSET-MSENDCARD | IDC-CBCARD |
M-PSET-MADDRESS | IDC-EADDR |
M-PSET-MCITY | IDC-ECITY |
M-PSET-MCONTRY | IDC-ECOUNTRY |
M-PSET-M- | IDC-EEMAIL |
EMAILADDRESS | |
M-PSET-MFAXNUMBER | IDC-EFAX |
M-PSET-M-FIRSTNAME | IDC-EFNAME |
M-PSET-HOMEPHONE | IDC-EHPHONE |
M-PSET- ADDRESS ID | IDC-EID |
M-PSET-M- LAST NAME | IDC-ELNAME |
M-PSET-M- NOTES | IDC-ENOTES |
M-PSET-M- | IDC-ESNAME |
SPOUSENAME | |
M-PSET-M- | IDC-ESTATE |
STATEORPROVINCE | |
M-PSET-M- | IDC-EWEXT |
WORKEXTENSION | |
M-PSET-MWORKPHONE | IDC-EWPHONE |
M-PSET-M-POSTALCODE | IDC-EZIP |
اگر دقت کرده باشید به کنترل تاریخ تولد ( BIRTHDATE) هیچ فیلدی اختصاص نداده ایم. برای دیدن تعریف فیلد روی کلاس رکوردست دو – کلیک کنید : می بینید که متغیر M-BIRTHDATE از نوع CTIME است و به همین دلیل است که در لیست فیلدهای پایگاه داده دیده نمی شود ، چون هیچ ماکرو یا تابعی برای قرار دادن یک متغیر CTIME در کنترلهای وجود ندارد مشکل دیگر متغیر های CTIME آن است که تاریخهای قبل از ۳۱ دسامبر ۱۹۶۹ نمی توانند کار کنند برای حل این مشکلات باید نوع متغییر تاریخ تولد را از CTIME به COLEDate تغییر دهیم.
به لیست ۱‑۷ ، خط ١٧ دقت کنید بعد از این تغییر می توانید متغییر M-birthdate را به کنترل IDC-EDOB وابسته کنید.
لیست ۱‑۷ : تعریف فایلد های پایگاه داده
تا بحال کد های ایجاد شده توسط جادوگرهای را دستکاری نکرده بودیم : اما مورد بالا یک استثناست. از آنجائیکه انواع Ctime و ColeDateTime بسیار شبیه یکدیگرند و توابعی که با آنها سر و کار داریم تفاوتی بین این دو نوع قایل نمیشوند تغییر فوق باعث بروز مشکل نخواهد شد شاید فکر کنید بعد از تغییر دادن نوع متغیر m-Birthdate و مرتبط کردن آن با کنترل IDC-EDOB آماده اید برنامه را کامپایل و اجرا کنید ، اما متاسفانه برنامه کامپایل نخواهد شد.خطایی که کامپایلر اعلام میکند چنین است: DDx-Fieldtext قابل تبدیل به نوع ColeDateTime نیست این تبدیل را خود ما باید انجام دهیم. به جادوگر کلاس بر گشته و متغیری راکه به کنترل IDC-EDOB نسبت دادیم حذف کنید و سپس متغیر جدیدی از نوع ColeDateTime تابع m-Birthdate برای آن تعریف کنید. در کلاس نما ، CdbOdbcview تابع DoDataExchange را باز کرده و خط های ۴ تا ۶ و ۲۶ تا ۲۸ را مطابق لیست ۱‑۸ به آن اضافه کنید.
لیست ۱‑۸ : تابع DoDataExchange
علاوه بر تغییرات فوق باید مقداری را که جادوگر کلاس در اول برنامه به متغیر m-Birthdate می دهد حذف کنید (در ایجاد هم باید کد نوشته شده توسط جادوگر برنامه را دستکاری کنیم ) برای اینکار کافیست جلوی این دستور از علامت // استفاده کنید ( به خط ۱۹ لیست ۱‑۹ ، نگاه کنید ).
لیست ۱‑۹ : سازنده کلاس Cdodbeset
حال اگر برنامه را کامپایل و اجرا کنیم ، خواهید دید که برنامهای کامل در اختیار دارید و میتوانید ضمن حرکت در میان رکورد های رکوردست ، آنها را دستکاری هم بکنید ( شکل ۱‑۱۰ ).
اضافه کردن رکورد جدید
تا اینجا بدون آن که حتی یک خط کد نوشته باشید (البته با کمی اغماض) برنامه ای کامل و عملیاتی دارید اما این برنامه نواقصی دارد. مثلآ هنوز نمیتوانید رکورد جدیدی به پایگاه داده اضافه کنید. برای اضافه کردن رکورد جدید ، ابتدا باید شماره ID رکورد بعدی را بدست آوریم و برای اینکار ID آخرین رکورد را گرفته و I به آن اضافه میکنیم. بعد از آن با تابع ADDNEW رکورد جدید در پایگاه داده ایجاد می کنیم ، ID جدید را به آن می دهیم و با تابع Update آن را در پایگاه داده ذخیره میکنیم. سپس با تابع Regucry رکوردست را به روز در میآوریم و با رفتن به آخرین رکورد به کاربر اجازه میدهیم تا رکورد جدید را مشاهده و Edit کند.
چون فیلد ID در این پایگاه داده یک فیلد Autolcroment است معمولآ نیازی نیست ما به آن مقدار بدهیم. اما برای اضافه کردن رکورد جدید به پایگاه داده ، این فیلد حتمآ باید مقدار معتبری داشته باشد. روشی که در مثال درس امروز بکار گرفته ایم در یک پایگاه داده چند کاربره[۲۹] کاربری ندارد چون تمام کاربران رکوردی با ID مشابه ایجاد خواهند کرد. برای حل این مشکل میتوانیم از یک روتین مرکزی برای محاسبه ID رکورد جدیدی استفاده کنیم و اجازه ندهیم تا کاربران خود آن را محاسبه کنند. روش دیگر استفاده از یک دستور SOL برای ایجاد رکورد جدید است چون در این حالت فیلد ID بطور خودکار افزایش داده خواهد شد.
برای پیاده سازی فرآیندی که شرح داده شد ابتدا باید تابعی برای محاسبه ID رکورد جدید بنوسیم. پس ، در کلاس CdbOdbcset تابع جدیدی بنام GetMaxID از نوع مخدل و با دسترسی public ساخته و کد لیست ۱‑۱۰ را در آن بنویسید.
سپس آیتم جدیدی با مشخصات جدول ۱‑۱۰ ، به منوی record اضافه کنید.
جدول ۱‑۱۰ : آیتم جدید منوی record
مقدار | خاصیت | شیء |
IDM-RECORD- | ID | Menu Entery |
NEW | ||
M&ew Record | Caption | |
Add a new | Prompt | |
Record/nNew record |
در جادوگر کلاس. تابعی برای رویداد COMMAND این آیتم ساخته و کد لیست ۱‑۱۱ را در آن بنویسید.
لیست ۱‑۱۱ : تابع on recordnew
در میان ابزار هم دگمه ای برای آیتم Record/New Record بسازید و سپس برنامه را کامپایل و اجرا کنید. حال قادرید رکوردهای جدیدی به پایگاه داده اضافه کرده و اطلاعات خود را در آنها وارد کنید.
حذف کردن رکورد
تنها کاری که باقی مانده ، امکان حذف کردن رکوردها از پایگاه داده است. برای این کار هم به آیتم جدیدی در منوی record نیاز داریم. در روال رویداد این آیتم ، بعد از حصول اطمینان از درخواست کاربر ، رکورد فعلی را با تابع Delete حذف می کنیم و سپس با تابع move prev به رکورد قبلی می رویم. برای اضافه کردن آیتم Record/delete Record از جدول ۱‑۱۱ کمک بگیرید. برای خواص آیتم Record/delete Record از جدول ۱‑۱۱ کمک بگیرید.
جدول ۱‑۱۱ : خواص آیتم Record/delete Record
مقدار | خاصیت | شیء |
IDM- | ID | Menue Entery |
RECORD-DELETE | ||
&Delete | Caption | |
Record | ||
Delete new curren | Prompt | |
Record/Delete record |
در جادوگر کلاس ، برای رویداد COMMAND این آیتم تابعی ساخته و کد لیست ۱‑۱۲ را در آن بنویسید.
لیست ۱‑۱۲ : تابع onrecordDelete
دگمه دیگری به نام IDM-RECORD-DELETE برای این آیتم به میله ابزار برنامه اضافه کرده و آن را کامپایل و اجرا کنید. اکنون با اضافه شدن امکان حذف رکورد ها یک برنامه پایگاه داده تمام و کمال در اختیار دارید ( به شکل ۱‑۱۱ نگاه کنید ).
- Microsoft ActiveX Data Objects (ADO) ↑
- Scripting ↑
- Object Linking and Embedding, Database, sometimes written as OLEDB or OLE-DB ↑
- Electronic mail, Email or E-mail ↑
- Object-oriented file system ↑
- Cairo ↑
- RecordSet ↑
- Objects ↑
- Collection ↑
- Username ↑
- Password ↑
- Transection control ↑
- Database ↑
- Stored procedures – توابع SQL که در درون پایگاه داده ذخیره شده اند ↑
- Precompiler directive ↑
- Import ↑
- Connection definition string ↑
- Data Access Object-DAO ↑
- ActiveX data object ↑
- Microsoft Access ↑
- FoxPro ↑
- Paradox ↑
- Structured Query Language ↑
- Oracle ↑
- Open Database Connectivity ↑
- Connect ↑
- Snapshot (computer storage) ↑
- Table ↑
-
Multiuser ↑