منتديات اليسير للمكتبات وتقنية المعلومات » منتديات اليسير العامة » منتدى تقنية المعلومات » قواعد البيانات ولغة فيجوال سي ، الجزء الثاني: استخدام قاعدة البيانات مع فيجوال سي

منتدى تقنية المعلومات هذا المنتدى مخصص للموضوعات الخاصة بتقنية المعلومات التي تتعلق بالمكتبات ومراكز مصادر المعلومات ومراكز مصادر التعلم.

إضافة رد
أدوات الموضوع تقييم الموضوع انواع عرض الموضوع
 
قديم Dec-07-2006, 11:01 AM   المشاركة1
المعلومات

AHMED ADEL
مكتبي متميز

AHMED ADEL غير متواجد حالياً
البيانات
 
العضوية: 18689
تاريخ التسجيل: Aug 2006
الدولة: الإمارات
المشاركات: 249
بمعدل : 0.04 يومياً


كتاب قواعد البيانات ولغة فيجوال سي ، الجزء الثاني: استخدام قاعدة البيانات مع فيجوال سي

قواعد البيانات ولغة فيجوال سي ، الجزء الثاني: استخدام قاعدة البيانات مع فيجوال سي

بقلم: نبيل حسين

تعرفنا في الجزء الأول على الأنواع المختلفة من قواعد البيانات، ثم صممنا قاعدة بيانات باستخدام برنامج أكسس، وسنتعرف في هذا الجزء أولاً على التقنيات البرمجية المختلفة التي توفرها لنا لغة فيجوال سي للتعامل مع قواعد البيانات المكتبية والعلائقية، ثم سنختار أنسب هذه التقنيات للتعامل مع قاعدة البيانات التي صممناها في الجزء الأول. وأذكّر أنَّ هذه المقالة موجهة بشكل رئيس لمن لديهم خبرة متوسطة على الأقل في لغة فيجوال سي .
لا توجد طريقة مباشرة تمكّن لغة برمجة مثل فيجوال سي من التعامل مع قاعدة بيانات مكتبية أو علائقية، لكن توجد عدة تقنيات تلعب دور الوسيط بين لغة البرمجة وقاعدة البيانات، وتمكنك من التخاطب مع قاعدة البيانات، وإرسال الأوامر لها، واستقبال النتائج منها. وسنعرض لأهم هذه التقنيات:
1. ODBC (Open Database Connectivity)
تم تصميم هذه التقنية في أوائل التسعينيات للتعامل مع قواعد البيانات العلائقية بشكل خاص، ويمكنك من خلال مجموعة الأوامر التي توفرها التخاطب مع أية قاعدة بيانات علائقية، تملك برنامج قيادة (Driver) خاص لتقنية ODBC.
تعتبر الأوامر البرمجية التي توفرها ODBC معقدة نسبياً، ودفع هذا شركة مايكروسوفت إلى إضافة أصناف (Classes) إلى مكتبتها الشهيرة (MFC) لتبسيط هذه التقنية، ونجحت بذلك. إذ يمكنك باستخدام هذه الأصناف أن ترسل أوامرك إلى قاعدة البيانات، وأن تستقبل النتائج منها ببساطة. لكن من عيوب هذه التقنية أنها لا تمكّنك من التعامل إلا مع قواعد البيانات العلائقية.

2. RDO (Remote Data Objects)
طوّرت هذه التقنية بشكل رئيس لتوفر طبقة مُبَسِطة لتقنية ODBC إلى مبرمجي لغة فيجوال بيسك. لذا فهي قريبة جداً من تقنية ODBC، لكنها أبسط كثيراً.

3. DAO (Data Access Objects)
توفر هذه التقنية مجموعة من الكائنات (Objects) للتخاطب مع قاعدة البيانات، وإرسال الأوامر لها. وهي مصممة بشكل رئيس للتعامل مع قواعد بيانات أكسس، لكن يمكنك استخدامها في التعامل مع قواعد بيانات أخرى من خلال المحرك Jet الذي توفره. وتمتاز هذه التقنية بسهولتها، كما إنَّ مكتبة MFC تحتوي على أصناف لتبسيط هذه التقنية بشكل أكبر. ومن مميزاتها أنها تمكنك أيضاً من تغيير الهيكل الخاص بقواعد بيانات أكسس، وذلك عبر إضافة الجداول لها مثلاً، أوتغيير هيئة أحد جداولها.
لكن من عيوب تقنية DAO أنها تستخدم طبقات برمجية كثيرة، فإذا أردت مثلاً التخاطب مع إحدى قواعد البيانات العلائقية باستخدام هذه التقنية، فإن ذلك سيأخذ بعض الوقت. لكنها ملائمة للتخاطب مع قواعد بيانات أكسس.

4. OLE DB (object-linking and embedding database)
تعتبر هذه التقنية أفضل من التقنيات السابقة، وهي من التقنيات الواعدة التي ستستمر شركة مايكروسوفت بدعمها في منتجاتها بشكل كبير، وتنصح شركة مايكروسوفت المبرمجين باستخدام هذه التقنية أو تقنية ADO المبسطة لها في البرامج الجديدة.
وتمتاز تقنية OLE DB عن التقنيات السابقة بميزتين، فهي أولاً تدعم تقنية COM، وذلك بتوفيرها لواجهة COM لبرمجة قواعد البيانات. وهي ثانياً، تدعم جميع قواعد البيانات العلائقية وغير العلائقية.
تعتبر هذه التقنية صعبة ومعقدة، وتحتاج إلى جهد برمجي للتعامل معها، كما هو الحال مع تقنية ODBC. لكنها تتمتع بمرونة واستقرار عاليين. ولا أريد أن أخوض في شرح محاسنها، ونقاط ضعفها، لكنها بكل تأكيد أفضل من سابقاتها، ويكفي القول بأنها تمثّل مستقبل تطوير قواعد البيانات على نظام ويندوز، وستركز مايكروسوفت جهودها لتطويرها، ولتطوير التقنية المبسطة لها ADO.

5. ADO (ActiveX Data Objects)
تقنية ADO مبنية على تقنية OLE DB، لكنها تبسط هذه الأخيرة بشكل كبير، ويمكنك استخدامها في العديد من لغات البرمجة، وهي مرنة إلى حد بعيد. وتتمتع تقنية ADO بمزايا تقنية OLE DB، لكن مع قدر أكبر من السهولة. وإذا أردت تقنية تتمتع بقدر كبير من السهولة، والاستقرار، وقوة الأداء، فلا أجد أفضل من النصح باستخدام هذه التقنية.
المثال التطبيقي

سنشرح برمجة برنامج بسيط باستخدام لغة فيجوال سي يوفر للمستخدم إمكانية البحث عن اسم كتاب في قاعدة بيانات، وسنستخدم تقنية ADO في التعامل مع قاعدة البيانات.
الخطوة الأولى هي تكوين الهيكل الرئيسي للبرنامج، ولعمل ذلك استخدم المعالج MFC AppWizard (exe)، الذي يمكنك الوصول إليه بالنقر على القائمة File، ثم اختيار البند New...، واختيار البند MFC AppWizard (exe) من الشريط Projects، ثم كتابة اسم المشروع، ولنطلق على مشروعنا هذا اسم Library، ثم ننقر على الزر OK.
انقر للتكبير
اختر بعد ذلك البندDialog based ، ثم انقر على الزر Finish. فتظهر نافذة تحتوي على معلومات عن المشروع الذي أنشأناه. انقر على الزر OK، فيفتح الإطار IDD_LIBRARY_DIALOG جاهزاً للتحرير. امسح الزر Cancel، والنص TODO: Place dialog controls here، وغيّر نص الزر OK إلى Close، وذلك بالنقر عليه بالزر الأيمن للماوس، ثم اختيار البند Properties...، وتغيير النص في مربع التحرير Caption إلى Close.
أضف عناصر التحكم الموضحة في الجدول 1 إلى هذا الإطار، ثم رتبها بطريقة مشابهة للشكل 1.
انقر للتكبير
تلاحظ أن الحقل Extended Styles يحتوي أحياناً على القيمة "Static edge"، ويعني هذا أن عليك النقر على الشريط Extended Styles في الإطار Text Properties، وتعيين المربع Static edge.
وربما يتبادر السؤال التالي إلى أذهان بعض القراء: لماذا أعطينا بعض عناصر التحكمات النصية Static Texts أرقام تعريف ID خاصة بها، مثل ID_PUBLISHER_STATIC، بينما اكتفينا في مرات آخرى برقم التعريف IDC_STATIC؟
تستخدم عناصر التحكم النصية الساكنة بشكل رئيس لكتابة النصوص في النوافذ أثناء مرحلة التصميم، كما استخدمناها في كتابة النص "Publisher:" مثلاً، وفي هذه الحالة، لسنا بحاجة لتغيير هذا النص برمجياً، ما يعني أننا لسنا بحاجة إلى إعطاء عنصر التحكم هذا رقماً تعريفياً خاصاً. أما في حالة عنصر التحكم ID_PUBLISHER_STATIC وغيره من العناصر، فإننا نريد أن نضع فيه اسم دار النشر التي نشرت الكتاب الذي يبحث عنه المستخدم، وقيمة هذا التحكم غير معروفة أثناء فترة التصميم، وعلينا أن نضعها فيه برمجياً في لاحقاً، لذا فنحن بحاجة إلى تغيير قيمة عنصر التحكم برمجياً، أي أننا بحاجة إلى ربط متغيّر بهذا التحكم، كي نستطيع من خلال هذا المتغيّر، تغيير قيمة عنصر التحكم.
انقر للتكبير
وخلاصة القول: إذا كنت لا تعتزم ربط متغير بتحكم نصي لتغيير قيمته مثلاً، فأبقِ قيمة رقمه التعريفي: IDC_STATIC، وإلا عليك تغيير قيمة الرقم التعريفي.
علينا الآن أن نُضيف الوظائف البرمجية إلى هذا الإطار، والخطوة الأولى هي ربط بعض المتغيرات بعناصر التحكم الموجودة في هذا الإطار، ولعمل ذلك اختر البند ClassWizard... من القائمة View. انقر بعد ذلك على الشريط Member Variables، ثم اختر البند CLibraryDlg من القائمة المنسدلة Class name:. يمكنك الآن النقر على كل من عناصر التحكم التي تجد رقمها التعريفي في الجدول 2، والنقر على الزر Add Variable...، وتعبئة حقول هذا الإطار وفقاً
علينا الآن تنفيذ بعدة خطوات، كي نتمكن من استخدام تعليمات ADO في برنامجنا من أجل التخاطب مع قاعدة البيانات. والحقيقة أنه توجد عدة طرق لعمل ذلك، وأسهلها هو استخدام تعليمة #import، وهي الطريقة التي تنصح بها شركة مايكروسوفت. ولعمل ذلك، افتح الملف "StdAfx.h"، وأضف إلى نهايته، وقبل تعليمة #endif الأخيرة، السطرين:

#include
#import "C:\program files\common files\system\ado\msado15.dll" no_namespace rename( "EOF", "adoEOF" )


وعندما تنفذ يعد ذلك عملية ربط البرنامج، فإنَّ يكون آلياً عدة ملفات رأسية (Header Files) يمكن أن نستخدمها لاحقاً.
تعتمد تقنية ADO على تقنية COM، وعليك لهذا أن تخبر البرنامج بالحاجة إلى مكتبات COM، ولعمل ذلك افتح الملف Library.cpp، ثم ابحث عن الوظيفة InitInstance، وأضف السطر التالي إلى بداية تلك الوظيفة:
AfxOleInit ( );
علينا الآن أن نضيف متغيّرين إلى الصنف CLibraryDlg، ولعمل ذلك، افتح الملف LibraryDlg.h، ثم أضف السطرين التاليين تحت التعليمة "protected:":

BOOL m_bIsConnectionOpen;
_ConnectionPtr m_pConnection;


بعد ذلك افتح الملف LibraryDlg.cpp، ثم اذهب إلى المنشئ "Constructor" الخاص بهذا الصنف، أي
CLibraryDlg::CLibraryDlg(CWnd* pParent /*=NULL*/)
وأضف إليه السطر التالي:
m_bIsConnectionOpen = FALSE;
وسنستخدم هذا المتغير للإشارة إلى إذا كان الاتصال مع قاعدة البيانات مفتوحاً أو مغلقاً.
أضف بعد ذلك السطور التالية إلى الوظيفة OnInitDialog، تحت السطر //TODO…:-

HRESULT hResult;

hResult = m_pConnection.CreateInstance (__uuidof(Connection));

if (SUCCEEDED(hResult))
{
hResult = m_pConnection->Open (bstr_t(L"Provider=Microsoft.Jet.OLEDB.3.51;Data Source=c:\\Library\\Library97.mdb;"),
_bstr_t(L""), _bstr_t(L""), adModeUnknown);

if (SUCCEEDED(hResult))
m_bIsConnectionOpen = TRUE;
}


عرفنا في البداية متغير من نوع HRESULT، وذلك كي نخزّن فيه النتيجة التي ترجعها بعض الوظائف. واستخدمنا المتغيّر "m_pConnection"، الذي عرّفناه سابقاً، لتكوين كائن للاتصال بقاعدة بيانات. ثم تأكدنا من أنَّ النتيجة التي أرجعتها الوظيفة "CreateInstance" إيجابية، فإذا كانت كذلك فإننا نفتح قاعدة البيانات التي صممنها في الجزء الأول من هذه المقالة، باستخدام الأمر Open. وتذكر أن تغيير المسار المذكور في القيمة:
Data Source=c:\\Library\\Library97.mdb
إلى المسار الذي توجد فيه قاعدة البيانات على قرصك الصلب.
نفحص بعد ذلك القيمة التي أرجعتها التعليمة Open، فإذا كانت إيجابية، فإن ذلك يعني أننا تمكّنا من فتح الاتصال مع قاعدة البيانات، ونقوم عندها بوضع القيمة TRUE في المتغيّر m_bIsConnectionOpen.
علينا أن نضيف وظيفةً تُنفذ عندما ينقر المستخدم على الزر Find it!، لتتم عملية البحث عن اسم الكتاب الذي أدخله المستخدم. ولعمل ذلك شغّل المعالج ClassWizard... من القائمة View، ثم انقر على الشريط Message Maps، وتأكد من أن الصنف المحدد ضمن القائمة Class name: هو CLibraryDlg. انقر على البند IDC_FIND_BUTTON ضمن القائمة Objects IDs:، ثم انقر على البند BN_CLICKED ضمن القائمة Messages، وانقر على الزر Add Function...، فتظهر نافذة تقترح عليك الاسم OnFindButton للوظيفة الجديدة. اقبل هذا الاسم، وانقر على الزر OK. انقر على الزر Edit Code ليتم فتح هذه الوظيفة للتحرير، وأضف الأسطر التالية إلى هذه الوظيفة:

if (!m_bIsConnectionOpen)
return;

UpdateData ( );

_RecordsetPtr pRecordSet;

CString str;
str.Format ("SELECT * FROM Books WHERE Book = '%s'", m_strEditBook);
_bstr_t bstrQuery (str);
_variant_t vRecsAffected (0L);

try
{
pRecordSet = m_pConnection->Execute (bstrQuery, &vRecsAffected, adOptionUnspecified);

if (!pRecordSet->GetadoEOF())
{
_variant_t vBook, vISBN, vAuthor, vPublisher, vPages;

vBook = pRecordSet->GetCollect (L"Book");
vISBN = pRecordSet->GetCollect (L"ISBN");
vAuthor = pRecordSet->GetCollect (L"Author");
vPublisher = pRecordSet->GetCollect (L"Publisher");
vPages = pRecordSet->GetCollect (L"Pages");

m_strBook = (BSTR)(_bstr_t)vBook;
m_strISBN = (BSTR)(_bstr_t)vISBN;
m_strAuthor = (BSTR)(_bstr_t)vAuthor;
m_strPublisher = (BSTR)(_bstr_t)vPublisher;
m_strPages = (BSTR)(_bstr_t)vPages;
}
else
AfxMessageBox ("Can't find this book!");

pRecordSet->Close ( );
}

catch( _com_error &e )
{
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());

CString strError;
strError.Format ("Source = %s\nDescription = %s\n", bstrSource, bstrDescription);
AfxMessageBox (strError);
}

UpdateData (FALSE);


تأكدنا في البداية من أنَّ الاتصال مع قاعدة البيانات مفتوح، ثم نقلنا محتويات عناصر التحكم إلى المتغيرات المرتبطة بها عن طريق الأمر UpdateData (FALSE)، ثم عرّفنا متغيّر من نوع _RecordsetPtr، لتخزين الحقول التي سنطلبها من قاعدة البيانات. عرّفنا متغيّر نصي، ووضعنا فيه سطر برمجي مكتوب بلغة SQL، يطلب تحديد جميع الحقول في الجدول Books، التي فيها قيمة الحقل Book مطابقة لاسم الكتاب الذي أدخله المستخدم في مستطيل التحرير، والذي خزّناه في المتغيّر m_strEditBook. عرّفنا بعد ذلك متغيّر من نوع _bstr_t، وهو نوع يسّهل علينا التعامل مع النوع BSTR، ووضعنا في هذا المتغيّر قيمة المتغيّر str. ثم عرّفنا متغيّر من نوع _variant_t، سنستخدمه فيما بعد.
حصرنا التعليمات الخاصة بطلب الحقول الخاصة باسم الكتاب الذي أدخله المستخدم بين قوسي تعليمة try، وهي تعليمة خاصة بالاستثناءات، فإذا حصل أي خطأ أثناء عملية طلب الحقول من قاعدة البيانات، فإنها ترسل استثناء إلى تعليمة catch التي تقوم بمعالجته.
تنفذ التعليمة الأولى ضمن قوسي تعليمة try، الأمر Execute عن طريق المتغيّر m_pConnection، والنتيجة الراجعة ستكون إما الحقول التي تحتوي على المعلومات الخاصة باسم الكتاب الذي أدخله المستخدم في حال وجود اسمه في قاعدة البيانات، أو لا شيء.
فحصنا بعد ذلك وجود أي حقول راجعة، فإذا وجدت، يعرّف البرنامج عدة متغيّرات من نوع _variant_t لنخزّن فيها قيم الحقول الراجعة، وذلك عن طريق استخدام الأمر GetCollect. بعد ذلك، وضعنا قيم هذه المتغيّرات في المتغيرات المرتبطة بعناصر التحكم. ثم أغلقنا الاتصال مع المتغيّر pRecordSet.
يتم تنفيذ التعليمات الخاصة بالتعليمة catch، في حالة وجود خطأ، فقط، وهي تعرض رسالة خطأ تخبرك عن سببه. وأنبه إلى إنَّ استخدام تعليمتي catch و try ضروري جداً، فإذا حصل خطأ، ولم تكن هاتان التعليمتان مستخدمتان، فإنَّ البرنامج سينهار بدون أن تعرف سبب ذلك.
شغّل المعالج ClassWizard...، وأضف وظيفة إلى البند IDOK، ثم انقر على الزر Edit Code، ففتح الوظيفة OnOK جاهزةً للتحرير. أضف الأسطر التالية تحت عبارة //TODO…:-

if (m_bIsConnectionOpen)
{
m_pConnection->Close ( );
m_bIsConnectionOpen = FALSE;
}


والغرض من إضافة هذه السطور، هو إغلاق الاتصال مع قاعدة البيانات، إذا كان مفتوحاً، عند إغلاق البرنامج. يظهر الشكل 2 النتائج التي حصلت عليها بعد أن أدخلت الاسم "Wallenstein".
انقر للتكبير












التوقيع
*لا إله إلا أنت سبحانك إني كنت من الظالمين*

كن كالنخيل عن الأحقاد مرتفع ،،، بالطوب يرمى فيقذف أطيب الثمر

http://arablibrariannet.blogspot.com/
  رد مع اقتباس
إضافة رد

مواقع النشر (المفضلة)


الذين يشاهدون محتوى الموضوع الآن : 1 ( الأعضاء 0 والزوار 1)
 

تعليمات المشاركة
لا تستطيع إضافة مواضيع جديدة
لا تستطيع الرد على المواضيع
لا تستطيع إرفاق ملفات
لا تستطيع تعديل مشاركاتك

BB code is متاحة
كود [IMG] متاحة
كود HTML معطلة

الانتقال السريع

المواضيع المتشابهه
الموضوع كاتب الموضوع المنتدى مشاركات آخر مشاركة
مكتبة اليسير ( إقرأ ما تريد .. وضع كتاب جديد !) د.محمود قطر عروض الكتب والإصدارات المتخصصة في مجال المكتبات والمعلومات 66 Apr-05-2014 03:17 PM
قواعد البيانات ولغة فيجوال سي - الجزء الأول: تصميم قاعدة البيانات AHMED ADEL منتدى تقنية المعلومات 2 Oct-21-2012 07:15 PM
حــزمة البـرمجيات CDS/ISIS عبدالعزيز الخبتي منتدى الأنظمة الآلية في المكتبات ومراكز المعلومات 9 Apr-20-2012 04:43 PM
ماهي المصادر البشرية التي يمكن أن تساعد المستفيدين في تحديد الوصول إلى مصادر الداخلية جآء الأمل منتدى الإجراءات الفنية والخدمات المكتبية 18 Oct-13-2011 12:29 PM


الساعة الآن 10:48 AM.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. جميع الحقوق محفوظة لـ : منتديات اليسير للمكتبات وتقنية المعلومات
المشاركات والردود تُعبر فقط عن رأي كتّابها
توثيق المعلومة ونسبتها إلى مصدرها أمر ضروري لحفظ حقوق الآخرين