Electronic Gilgamesh

عزيزي الزائر كما هو واضح بأنك زائر للمنتدى لذى نود ان ندعوك الى الدخول ان كانت لديك عضوية او التسجيل في المنتدى نتشرف بتواجدك معنا حيث المعلومة الجديدة والدروس التعليمية الحصرية
Electronic Gilgamesh

For information & communication technology


    درس في ADO.NET من الصفر إلى الإحتراف الدرس الثاني

    شاطر

    Admin
    Admin
    Admin

    عدد الرسائل : 117
    تاريخ التسجيل : 02/09/2008

    درس في ADO.NET من الصفر إلى الإحتراف الدرس الثاني

    مُساهمة من طرف Admin في الإثنين ديسمبر 27, 2010 7:42 pm

    توقفنا في حديثنا الماضي أن أغلب من يرغبون تعلم برمجة قواعد البيانات من خلال ADO.NET يضيعون في التفريق بين الاتصال المتصل (Connection Oriented ) و الاتصال المنفصل ( Connectionless Oriented ) . والسبب في اعتقادي هو ضعف فهم الآلية التي يعمل بها كل منهما من ناحية ، والخلط بينهما من ناحية أخرى . ولكي نزيل هذه المشكلة سوف نتحدث عن كل منهما بشكل مستقل ..
    وقبل ذلك يجب أن نوضح أمر مهم وهو : أنه عند بدأ مشروع جديد للاتصال بقاعدة البيانات يجب قبل كل شيء أن نستدعي فضاء الأسماء المناسب لمزود البيانات (Provider ) الذي نتعامل معه ، والذي تندرج تحته كائناته الخاصة به للاتصال بقاعدة البيانات و ومعالجتها ، ومن مميزات استدعاء فضاء الأسماء أنه يغنينا عن كتابة مسار الكائنات التي سوف نستخدمها ، فقط نكتب اسم الكائن ..

    فعند التعامل مع قواعد بيانات Microsoft Office Access نستدعي فضاء الأسماء
    System.Data.OleDb وذلك بكتابة الكود التالي في أعلى صفحة الكود :



    Imports System.Data.OleDb


    وتندرج تحته مجموعة من الكائنات ولكن كل ما يهمنا منها كمبتدئين ما يلي :
    OleDbCommand , OleDbConnection , OleDbDataAdapter , OleDbDataReader , OleDbParameter , OleDbCommandBuilder , OleDbTransaction. , OleDbException .

    وعند التعامل مع قواعد بيانات SQL Server نستدعي فضاء الأسماء System.Data.SqlClient وذلك بكتابة الكود التالي في أعلى صفحة الكود :


    Imports System.Data. SqlClient


    وتندرج تحته مجموعة من الكائنات ولكن ما يهمنا منها كمبتدئين ما يلي :
    SqlCommand , SqlConnection , SqlDataAdapter , SqlDataReader , SqlParameter , SqlCommandBuilder , SqlTransaction. SqlException .

    ملاحظة : الإخوة الذين يستخدمون SQL Server يستطيعون أن يكملوا معنا الدرس دون مشاكل ، وكل ما عليهم هو أن يستبدلوا عبارة OleDb بعبارة Sql .

    * الاتصال المتصل (Connection Oriented ) :

    وتتلخص فكرته في أن نقوم بإجراء اتصال مع قاعدة البيانات ، وبعد قبوله نقوم بفتح الاتصال ثم نقوم بتنفيذ مجموعة من الأوامر التي نحتاجها ( مثل قراءة البيانات من أجل عرضا للمستخدم ، أو تحديث البيانات من إضافة و تعديل حذف وحفظ ، أو إلغاء عملية التحديث ، أو البحث عن بيانات معينة أو ألإبحار والتجول في البيانات ) وبعد الانتهاء نقوم بإغلاق الاتصال ، ويعتبر إغلاق الاتصال ضرورياً لان معظم مصادر البيانات تدعم عدداً محدوداً من الاتصالات المفتوحة . وهذا يعني أننا يجب أن نحافظ على الاتصال حتى ننتهي من الهدف الذي تم من أجله الاتصال .
    وهو مناسب " في حاله بناء التطبيقات المفردة ، أي عندما يكون للنظام مستخدم واحد وتوجد واجه المستخدم ومخزن قاعدة البيانات على نفس الجهاز . " ( أ. SOLO.NET ، مشرف منتدى ال VB.NET )

    ولا يمكن استخدامه في حالة التطبيقات التي يحتاجها الكثير من المستخدمين ، ويرجع السبب في ذلك إلى أن مثل هذا النوع من الاتصال يستهلك جزءاً مهم من موارد النظام ، ويترتب علية تدني أداء هذه التطبيقات . ولأن معظم مصادر البيانات تدعم عدداً محدوداً من الاتصالات المفتوحة كما أسلفنا سابقاً . ويعد ذلك من أكبر عيوب هذا النوع بالإضافة إلى أنه يتطلب كتابة الكثير من الأكواد البرمجية كما سوف نشاهد في الجزء العملي من الدرس ، وذلك يعد عائق كبير أمام صيانة الكود وتحديثه من وقت لأخر .
    ولعمل اتصال من هذا النوع نحتاج إلى ثلاث كائنات أساسية نستخدمها على النحو التالي :

    1- كائن الاتصال OleDbConnection : من أجل الاتصال بقاعدة البيانات .
    2- فتح الاتصال بقاعدة البيانات .
    3- كائن الأوامر OleDbCommand : في اعتقادي أنه يمثل القلب للاتصال المتصل ، وهو من أجل تنفيذ عملية قراءة البيانات المخزنة في قاعدة البيانات ، أو تحديثها ( من إضافة وتعديل وحذف ) ، ويعتمد في تكوينه على وجود اتصال مفتوح مع قاعدة البيانات ، وعلى جملة الاستعلام البنيوية SQL ( وهي لغة قياسية لبناء ومعالجة قواعد البيانات ومحتوياتها ، وتتضمن هذه اللغة تعليمات من أجل إضافة ، تعديل ، حذف ، ترتيب ، و اختيار سجلات ) . ومن أهم خصائصه :-

    - Connection : ويجب أن يحمل اسم الاتصال الذي سوف يستخدمه كائن الأمر .

    - CommandType : وله ثلاثة قيم ، القيمة Text ( لتنفيذ جملة استعلام بنيوية SQL ) ، القيمة StoredProcedur ( لتنفيذ إجراء مخزن في قاعدة البيانات ) ، القيمة TableDairect ( للتعامل مع جدول واحد ) .
    ملاحظة : سوف نستخدم في درسنا القيمة Text فقط وهي ما تهمنا كمبتدئين .

    - CommandText : ويعتمد على القيمة التي اخترناها في الخاصية السابقة ( CommandType) ، لذلك سوف يكون لدينا ثلاث مدخلات متناسبة معها على التوالي ، الإدخال الأول عبارة عن جملة استعلام بنيوية والتي سوف يتم تنفيذها سواء لاختيار أو تحديث السجلات ، المدخل الثاني عبارة عن اسم الإجراء المخزن في قاعدة البيانات والذي نريد تنفيذه ، والمدخل الثالث عبارة عن اسم الجدول الذي نريد التعامل معه .

    - Parameters : ويستخدم للوصول إلى معاملات الإدخال و الإخراج والقيم العائدة .

    بعد تجهيز الخصائص السابقة لكائن الأمر ونريد تنفذ الأعمال المطلوبة منه عند حصوله على تيار من البيانات ، لدينا ثلاثة طرق يتم بها العمل :

    الطريقة الأولى ( ExecuteReader ) وهي أحد خصائص كائن الأمر وتقوم بتنفيذ استعلام بنيوي يرجع لنا مجموعة من الصفوف الموجودة في قاعدة البيانات وهو ما يتطلب استرجاع هذه النتيجة بواسطة الكائن OleDbDataReader والذي سون نتحدث عنه بعد قليل .

    الطريقة الثانية ( ExecuteNonQuery ) وهي أحد خصائص كائن الأمر وتقوم بتنفيذ استعلام بنيوي يقوم بتحديث قاعدة البيانات ( من إضافة ، تعديل ، و حذف ) أو تكوين قاعدة بيانات والنتيجة التي ترجع هي عدد الصفوف المتأثرة بالأمر .

    الطريقة الثالثة ( ExecuteScalar ) وهي أحد خصائص كائن الأمر وتقوم بتنفيذ استعلام بنيوي يرجع لنا قيمة واحده فقط من قاعدة البيانات .

    4- كائن قراءة البيانات OleDbDataReader : ويقوم بقراءة تيار من البيانات القابلة للقراءة فقط وفى اتجاه واحد يكون للأمام فقط . ويعتمد في تكوينه على وجود كائن أمر مبني على جملة استعلام مصممة لاختيار سجلات . ومن أهم خصائصه :

    - Read : ومهمتها هي توجه قارئ البيانات إلى قراءة الصف الأول من النتائج ، وترجع القيمة True إذا وجد صف أو False إذا لم يوجد صف .

    - Item : ومهمتها هي استرجاع قيمة العمود إما باستخدام أسم العمود أو رقمه .

    - GetValues : ومهمتها هي استرجاع قيمة الصف كاملاً .

    - isDBnull : ومهمتها هي اختبار فيما إذا كانت البيانات تحتوي على قيم Null .

    - Close : ومهمته هي إغلاق كائن قارئ البيانات ولا يقوم بإغلاق الاتصال . مع ملاحظة أنه يجب دائماً إغلاق قارئ البيانات عند الانتهاء منه لان كائن الأوامر إذا كان يحتوي على معاملات إخراج أو قيم جديدة لن يكون في الإمكان التعامل معها إلى أن يتم الانتهاء من إغلاق كائن DataReader .

    5- إغلاق الاتصال بقاعدة البيانات .

    * وهنا نصل للجانب العملي من الدرس :

    سوف نركز في الجانب العملي على الثلاثة طرق التي يتم بها العمل في كائن الأوامر OleDbCommand والذي قلنا فيما سبق أنه يمثل القلب .

    مثال 1 : الطريقة ExecuteReader ، ماذا لو فرضنا أننا نريد أن نقرأ مجموعة من البيانات الموجودة في ملف قاعدة البيانات مصمم ببرنامج Microsoft Office Access والمسمى ( Note ) والذي من المفترض أن يوجد في نفس مسار مشروعنا ، وهذا الملف محمي بكلمة المرور ( ado.net ) وهو يحتوي على جدول اسمه ( Information ) والذي يحتوي بدوره على الحقول التالية ( ID ويحمل خاصية الترقيم التلقائي ويعد مفتاح أساسي ، Name ويحمل خاصية كونه نص ، Phone ويحمل خاصية كونه رقم ) ، ثم نعرض هذه البيانات في مربعات نص ، فكما تعلما سوف يكون العمل على النحو التالي ...

    أولاً : نقوم بفتح مشروع جديد و نضيف مربعات النص التي سوف نعرض فيها قيم الحقول الموجودة في الجدول Information ...

    ثانياً : استدعاء فضاء الأسماء الخاص بمزود بيانات برنامج Microsoft Office Access ، وذلك بكتابة الكود التالي في أعلى صفحة الكود ..

    Imports System.Data.OleDb



    ثالثاً :
    التصريح عن الكائنات التي نحتاجها كمتغيرات في منطقة Declarations في صفحة الكود وذلك كي يتم التعرف علية في مختلف أجزار النموذج
    ، في البداية نقوم بتهيئة كائن الاتصال وليكن اسمه Conn ، كما في الكود التالي ...


    Dim Conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\ ConnectedMode\Note.mdb;User ID=Admin;Jet OLEDB:Database Password=ado.net")

    ولكي لا نجعل برنامجنا الذي نتدرب علية مقيد بمسار ثابت وهو " C:\ ConnectedMode\MyNote.mdb " نستطيع أن نجعله أكثر مرونة بحيث يعمل على أي مسار شرط أن يتواجد ملف قاعدة البيانات والملف التنفيذي للبرنامج في نفس الموقع ، وذلك من خلال العبارة التالية "|DataDirectory|" بحيث يصبح الكود السابق كما يلي ..


    Dim Conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|Note.mdb;User ID=Admin;Jet OLEDB:Database Password=ado.net")

    ثم نقوم بالتصريح عن كائن الأوامر وليكن اسمه MyCmd كما في الكود التالي ..

    Dim MyCmd As New OleDbCommand


    ثم نقوم بالتصريح عن كائن القراءة وليكن اسمه MyReader كما في الكود التالي ..


    Dim MyReader As OleDbDataReader


    رابعاً : في حدث تحميل النموذج نقوم بفتح الاتصال ..

    Conn .Open

    خامساً : نقوم بتهيئة كائن الأمر ( باستخدام جملة استعلام بنيوية تقوم بتحديد حقول معينة من الجدول الموجود في قاعدة البيانات ) كما ذكرنا في الجزء ألنضري من الدرس ، وذلك من خلال الكود التالي ..


    MyCmd.Connection = Conn
    MyCmd.CommandType = CommandType.Text
    MyCmd.CommandText = "SELECT ID, Name, Phone FROM Information ORDER BY Name
    ;"


    سادساً : نقوم بتهيئة كائن القراءة ، وذلك بإسناد الطريقة ExecuteReader ( التابعة لكائن الأمر MyCmd ) إلية ، كما في الكود ..

    MyReader = MyCmd.ExecuteReader


    سابعاً : قبل إسناد قيم الحقول إلى مربعات النص نتحقق من أن كائن القراءة وجد صفوف تحتوي على بيانات من خلال أداة الشرط IF .. Then .. Else .. End If وباستخدام الخاصية Read ، وفي حالة توفر البيانات نقوم بإسناد قيمة كل حقل لمربع النص الخاص به من خلال الخاصية Item ، كما في الكود التالي ..

    If MyReader.Read Then
    txtID.Text = MyReader.Item("ID")
    txtName.Text = MyReader.Item("Name")
    txtPhone.Text = MyReader.Item("Phone")
    Else
    MsgBox(" Empty ", MsgBoxStyle.Exclamation)
    End If

    ثامناً : إغلاق كلاً من كائن القراءة وكائن الاتصال ، كما في الكود التالي ...


    MyReader.Close()
    Conn.Close()

    مثال 2 : الطريقة ExecuteNonQuery ، استنادا للمثال السابق ماذا لو أردنا تحديث بياناتنا ( إضافة ، تعديل ، و حذف ) ، إذا فلنتابع شرح هذا المثال ..
    أولاً : نضيف ثلاثة (Button ) ، ونسمي الأول btnAddNew والثاني btnUpdate والثالث btnDelete .
    ثانياً : في حدث النقر لـ btnAddNew نقوم بما يلي ..
    1- نقوم بفتح الاتصال ..

    Conn .Open

    2- نقوم بتهيئة كائن أمر جديد ونسميه InsertCommand ( باستخدام جملة استعلام بنيوية تقوم بإضافة بيانات مخزنة في Parameters ( ونرمز لها بالرمز ? ) لحقول معينة من الجدول الموجود في قاعدة البيانات ) كما ذكرنا في الجزء ألنضري من الدرس ، وذلك من خلال الكود التالي ..


    Dim InsertCommand As New OleDbCommand
    InsertCommand.Connection = Conn
    InsertCommand.CommandType = CommandType.Text
    InsertCommand.CommandText = "INSERT INTO Information(Name,Phone) VALUES(?,?);"

    ملاحظة : لم نضيف أي قيمة للحقل ID لأنه له خاصية الترقيم التلقائي .

    3- نقم بإعطاء قيم للـ Parameters الموجودة في جملة الاستعلام من خلال الخاصية Parameters التابعة لكائن الأمر ، وذلك بعد تنظيفه من إي Parameters ( فيما إذا كانت هناك أي Parameters مستخدمة سابقاً ) ..


    InsertCommand.Parameters.Clear()
    InsertCommand.Parameters.AddWithValue("?", txtName.Text)
    InsertCommand.Parameters.AddWithValue("?", txtPhone.Text)

    4- نطبق الطريقة ExecuteNonQuery والتي سوف تقوم بتنفيذ استعلام تحديث الجدول ..


    InsertCommand.ExecuteNonQuery()


    5- نتخلص من كائن الأمر InsertCommand لأننا انتهينا منه وحتى لا يستهلك جزاء من موارد النظام ، ثم نغلق الاتصال بقاعدة البيانات ونعرض رسالة بنجاح العملية ..


    InsertCommand.Dispose()
    Conn.Close()
    MsgBox(" OK ", MsgBoxStyle.Information)

    ثالثاً : في حدث النقر لـ btnUpdate نقوم بما يلي ..
    1- نقوم بفتح الاتصال ..

    Conn .Open


    2- نقوم بتهيئة كائن أمر جديد ونسميه UpdateCommand ( باستخدام جملة استعلام بنيوية تقوم بتحديث بيانات مخزنة في Parameters ( ونرمز لها بالرمز ? ) لحقول معينة من الجدول الموجود في قاعدة البيانات وذلك اعتمادا على قيمة الحقل ID كمعرف للسجل الذي نريد تحديثه ) ، وذلك من خلال الكود التالي ..

    Dim UpdateCommand As New OleDbCommand
    UpdateCommand.Connection = Conn
    UpdateCommand.CommandType = CommandType.Text
    UpdateCommand.CommandText = "UPDATE Information set Name=? , Phone=? WHERE Id
    =?;"


    ملاحظة : لم نقوم بتعديل قيمة الحقل ID لأنه له خاصية الترقيم التلقائي .

    3- نقم بإعطاء قيم للـ Parameters الموجودة في جملة الاستعلام من خلال الخاصية Parameters التابعة لكائن الأمر ، وذلك بعد تنظيفه من إي Parameters ( فيما إذا كانت هناك أي Parameters مستخدمة سابقاً ) ..


    UpdateCommand.Parameters.Clear()
    UpdateCommand.Parameters.AddWithValue("?", txtName.Text)
    UpdateCommand.Parameters.AddWithValue("?", txtPhone.Text)
    UpdateCommand.Parameters.AddWithValue("?", txtID.Text)

    4- نطبق الطريقة ExecuteNonQuery والتي سوف تقوم بتنفيذ استعلام تحديث الجدول ..


    UpdateCommand.ExecuteNonQuery()


    5- نتخلص من كائن الأمر UpdateCommand لأننا انتهينا منه وحتى لا يستهلك جزاء من موارد النظام ، ثم نغلق الاتصال بقاعدة البيانات ونعرض رسالة بنجاح العملية ..


    UpdateCommand.Dispose()
    Conn.Close()
    MsgBox(" OK ", MsgBoxStyle.Information)

    رابعاً : في حدث النقر لـ btnDelete نقوم بما يلي ..
    1- نقوم بفتح الاتصال ..


    Conn .Open

    2- نقوم بتهيئة كائن أمر جديد ونسميه DeleteCommand ( باستخدام جملة استعلام بنيوية تقوم بحذف السجل الحالي من قاعدة البيانات وذلك اعتمادا على قيمة الحقل ID كمعرف للسجل الذي نريد حذفه والتي سوف نقوم بتخزينها في Parameter ( ونرمز له بالرمز ? ) ) ، وذلك من خلال الكود التالي ..

    Dim DeleteCommand As New OleDbCommand
    DeleteCommand.Connection = Conn
    DeleteCommand.CommandType = CommandType.Text
    DeleteCommand.CommandText = " DELETE FROM Information WHERE id = ?; "


    3- نقم بإعطاء قيمة للـ Parameter الموجود في جملة الاستعلام من خلال الخاصية Parameters التابعة لكائن الأمر ، وذلك بعد تنظيفه من إي Parameters ( فيما إذا كانت هناك أي Parameters مستخدمة سابقاً ) ..


    DeleteCommand.Parameters.Clear()
    DeleteCommand.Parameters.AddWithValue("?", txtID.Text)


    4- نطبق الطريقة ExecuteNonQuery والتي سوف تقوم بتنفيذ استعلام تحديث الجدول ..


    DeleteCommand.ExecuteNonQuery()


    5- نتخلص من كائن الأمر DeleteCommand لأننا انتهينا منه وحتى لا يستهلك جزاء من موارد النظام ، ثم نغلق الاتصال بقاعدة البيانات ونعرض رسالة بنجاح العملية ..


    DeleteCommand.Dispose()
    Conn.Close()
    MsgBox(" OK ", MsgBoxStyle.Information)


    مثال 3 : الطريقة ExecuteScalar ، استنادا للمثال الأول ماذا لو أردنا
    معرفة عدد السجلات المخزنة في الجدول Information ، إذا فلنتابع شرح هذا المثال ..
    أولاً : نضيف Button ، ونسميه btnCountId .
    ثانياً : في حدث النقر لـ btnCountId نقوم بما يلي ..
    1- نقوم بفتح الاتصال بقاعدة البيانات ..


    Conn.Open()


    2- نقوم بتهيئة كائن أمر جديد ونسميه CountIdCommand ( باستخدام جملة استعلام بنيوية تقوم بإعطائنا عدد السجلات المخزنة في الجدول Information ) ، وذلك من خلال الكود التالي ..

    Dim CountIdCommand As New OleDbCommand
    CountIdCommand.Connection = Conn
    CountIdCommand.CommandType = CommandType.Text
    CountIdCommand.CommandText = "SELECT Count(id) AS CountID FROM Information;"


    3- نقم بالتصريح عن متغير من نوع String ونسميه CountId على سبيل المثال ، وذلك كي نخزن فيه القيمة التي سوف يعود بها كائن الأمر بعد أن نمرر له الخاصية ExecuteScalar ..


    Dim CountId As String = CountIdCommand.ExecuteScalar()



    4- نقوم بعرض MsgBox يبين لنا القيمة المخزنة في المتغير CountId وهي هنا عدد السجلات الموجودة في الجدول Information ..


    MsgBox(CountId, MsgBoxStyle.Information)


    5- نتخلص من كائن الأمر CountIdCommand لأننا انتهينا منه وحتى لا يستهلك جزاء من موارد النظام ، ثم نغلق الاتصال بقاعدة البيانات ونعرض رسالة بنجاح العملية ..


    InsertCommand.Dispose()
    Conn.Close()
    MsgBox(" OK ", MsgBoxStyle.Information)


    الكائن الرابع : Transaction ، لم أحب أن ضيفه للكائنات الثلاثة الأولى لأني أعتقد بأنه فرعي وليس أساسي ، و وضيفته أمنيه بحته ، حيث يستخدم هذا الكائن غالبا عند عملية تحديث مجموعة سجلات مرتبطة مع بعضها دفعة واحدة ، فإذا فشل في تحديث أحدهم يتم إلغاء العملية بالكامل ، على سبيل المثال : في الحسابات البنكية ، عند سحب مبلغ من حساب أحد الأشخاص و إيداعه في حساب شخص أخر ، فثل هذه العملية يجب أن تحدث دفعة واحده ، ولو حدث أي مشكله فنية في العملية يجب إلغاء هذه العملية بالكامل .
    ومن أهم خصائص الكائن Transaction هي الخصيتان (Commit و Rollback ) .
    حيث أن الخاصية Commit تدل على نجاع العملية بدون مشاكل أو أي أخطاء وتسمح بتحديث البيانات ، و في حاله عدم تحقق شرط معين أو حدوث خطأ فإن الخاصية Rollback تقوم بعمل تراجع وتلغي العملية .
    ولكي نهيئ الكائن Transaction يجب أن نصرح عنه كمتغير كما في الكود ...

    Dim MyTransaction As OleDbTransaction


    ثم نستدعي الخاصية BeginTransaction التابعة لكائن الاتصال ونسندها له ، كما يلي ..


    MyTransaction = Conn.BeginTransaction


    ، ثم نهيئ كائن الأمر ( على سبيل المثال InsertCommand ) الذي نريد منه تحديث البيانات بإضافة سجل جديد ، وذلك باستدعاء الخاصية Transaction التابعة له وإسناد الكائن Transaction له ..


    InsertCommand.Transaction = MyTransaction


    وبعد تنفيذ الخاصية ExecuteNonQuery لكائن الأمر نقوم بإستدعاء الخاصية Commit التابعة للكائن Transaction وذلك لتأكيد قبول العملية ونجاحها ..


    MyTransaction.Commit()


    وفي حالة وجود أي مشكلة نستدعي الخاصية Rollback التابعة للكائن Transaction وذلك للقيام بإلغاء العملية ...


    MyTransaction.Rollback ()


    لذلك ننصح تعشيش كل العمليات التي يتوقع وجود مشاكل بها داخل دالة اكتشاف الأخطاء Try...Catch…Finally .

    المثال الرابع : الكائن Transaction ، بالرجوع للمثال الثاني ونريد تعديل بيانات السجل الحالي ونريد أن نستخدم الكائن Transaction كي نضمن عدم حدوث أخطاء وأن كل البيانات المطلوبة قد تم تحديثها ، والتراجع عن التحديث بالكامل في حالة لم يتم تحديث حقل من الحقول . وللقيام بذلك نتبع الأتي ..
    في حدث النقر لـ btnUpdate نقوم بما يلي ..
    1- نقوم بالتصريح عن متغيرين ، الأول كائن Transaction ونعطيه الاسم MyTransaction ، والثاني Command ونعطيه الاسم UpdateCommand ...


    Dim MyTransaction As OleDbTransaction
    Dim UpdateCommand As New OleDbCommand

    2- نقوم بتعشيش دالة اكتشاف الأخطاء Try...Catch…Finally ( مع ملاحظة أننا في جزئية الدالة Catch قمنا بالتصريح عن متغير أسميناه Filed من نوع OleDbException وهو من الكائنات التابعة لفضاء الأسماء System.Data.OleDb ونستفيد منه في الحصول على معلومات عن سبب الخطأ عند حدوثه في مصدر البيانات . ) كما يلي ..

    expand | plain text

    Try
    ' العمليات التي نرغب في اصطياد أخطائها إن وجدت
    Catch Filed As OleDbException
    ' الأخطاء التي تم اصطيادها ، بالإضافة للتصحيح المناسب لها
    Finally
    ' العمليات التي يجب تنفيذها على كل حال
    End Try



    ملاحظة : في الجزء الذي يحتوي على العمليات التي نرغب في اصطياد أخطائها إن وجدت من دالة Try نقوم بما يلي ..

    3- نقوم بفتح الاتصال ..
    expand | plain text

    Conn .Open


    4- استنادا لما تعلمناه في السطور السابقة نقوم بإعداد وتجهيز كلاً من الكائن Transaction والكائن Command ( مع ملاحظة أننا استخدمنا هذه المرة الخاصية ExecuteNonQuery لتحديث الحقل Name لوحده ثم استخدمناها مرةً أخرى لتحديث الحقل Phone ، مع تعمد كتابة خطأ في جملة الاستعلام التي نحدث بها الحقل Phone وبالتحديد في الكلمة "UPDATE" والتي كتبناها ABDATE"" ، وذلك حتى نتعرف على الطريقة التي سوف يتم بها اصطياد الخطأ وكيف سوف يتم تصحيحه ) ...
    expand | plain text

    MyTransaction = Conn.BeginTransaction
    UpdateCommand.Connection = Conn
    UpdateCommand.Transaction = MyTransaction
    UpdateCommand.CommandType = CommandType.Text
    UpdateCommand.CommandText = "UPDATE Information set Name=? WHERE Id =?;"
    UpdateCommand.Parameters.Clear()
    UpdateCommand.Parameters.AddWithValue("?", txtName.Text)
    UpdateCommand.Parameters.AddWithValue("?", txtID.Text)
    UpdateCommand.ExecuteNonQuery()
    UpdateCommand.CommandText = "ABDATE Information set Phone=? WHERE Id =?;"
    UpdateCommand.Parameters.Clear()
    UpdateCommand.Parameters.AddWithValue("?", txtPhone.Text)
    UpdateCommand.Parameters.AddWithValue("?", txtID.Text)
    UpdateCommand.ExecuteNonQuery()


    5- نقوم باستدعاء الخاصية Commit التابعة للكائن Transaction وذلك لتأكيد قبول العملية ونجاحها مع عرض رسالة تفيد بنجاح العملية ..
    expand | plain text

    MyTransaction.Commit()
    MsgBox(" OK ", MsgBoxStyle.Information)



    ملاحظة : في الجزء المسمى Catch من دالة Try والذي يحتوي على الأخطاء التي تم اصطيادها ، بالإضافة للتصحيح المناسب لها نقوم بما يلي ..
    6- نستدعي الخاصية Rollback التابعة للكائن Transaction وذلك للقيام بإلغاء العملية ، ثم نعرض رسالة نصية توضح لنا معلومات عن الخطأ الذي وقع أثناء تنفيذ البرنامج ...


    MyTransaction.Rollback()
    MsgBox(Filed.Message, MsgBoxStyle.Exclamation)

    ملاحظة : في الجزء المسمى Finally من دالة Try والذي يحتوي على العمليات التي يجب تنفيذها على كل حال ، نقوم بما يلي ..
    7- نتخلص من كائن الأمر UpdateCommand لأننا انتهينا منه وحتى لا يستهلك جزاء من موارد النظام ، ثم نغلق الاتصال بقاعدة البيانات ..


    UpdateCommand.Dispose()
    Conn.Close()


    ملاحظة : لقد استفدت كثيراً في شرح هذا الكائن من درس قدمه الأخ koao لذلك أحب أن أشكره على ذلك .

    ** هنا ينتهي حديثنا اليوم ، ونأخذ قسطاً من الراحة ، لكي نستوعب هذه الجرعة من المعلومات ونصحح أخطائها إن وجدت ، ونعلق على الغير مفهوم منها ، و نكمل فيما بعد شرح ما تبقى من الدرس وذلك في المشاركات القادمة ..

    ملاحظة : موضوعنا القادم يعد متعة برمجة قواعد البيانات الحقيقية ، وهو الاتصال المنفصل ( Connectionless Oriented ) ، والذي كما أسلفنا يعتبر الأمثل في التعامل مع قواعد البيانات ، ويغنينا عما سواه . إلا أننا كان لا بد لنا من تعلم كيفية التعامل مع الاتصال المتصل (Connection Oriented ) لأنه يحل لنا بعض الإشكالات البرمجية في بعض البرامج ، رغم إننا لم نتناول كل جوانبه ، ولكني أحب أن يعلم الجميع أنني أفرغت كل ما بجعبتي من معلومات عنه ، ومن يملك المزيد فليكسب أجرنا ويعلمنا مما علمه الله ،

    ((سبحانك اللهم وبحمدك، أشهد أن لا إله إلا أنت، أستغفرك وأتوب إليك ))
    أمثلة الجزأ الثاني من الدرس توجد في الملف المرفق ..



    منقول للفائدة

      الوقت/التاريخ الآن هو الخميس ديسمبر 08, 2016 2:18 am