برجاء تسجيل الإعجاب بالصفحة لتصلك كتاباتي على فيسبوك

المتابعون للمدونة

الثلاثاء، 21 فبراير، 2017

كوز المحبة



اثنان في واحد (ليس برت بلاس)
(13)
كوز المحبة
 

كان أحمد معاطي يفتح ملزمة الرياضيات، حينما سقطت منها ورقة مطوية.. انحنى معاطي ليلتقطها وفضها ليجد فيها ما يلي:

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

محمد حمدي: كاتب خيال علمي مبتدئ.. لن يفيدك بشيء سوى في تمييز محمد علي الذي صفعه في فكه، من محمد علي الذي لم تصفعه ناني على خده!!

أحمد عبد العزيز: مثقف متفيهق ومدخن شره.. لن يفيدك بشيء سوى إلهاء النحاس بحواراته العبثية أثناء تنفيذ المهمة.

ملحوظة: هذه الورقة ستحترق بعد خمس ثوان من قراءتك لها، فإن لم تفعل (وهذا هو الاحتمال المؤكد) فقم بإحراقها أنت!

ملحوظة أخرى: هناك شريط ستجده في جهاز التسجيل، لو قمت بتشغيله، فستسمع الموسيقى المميزة لمسلسل المهمة المستحيلة.. أبوس يدك لا داعي لإحراقه فقد استعرناه من أحمد الحريري.

***

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

***

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

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

وطبعا قوبل كلامه باستهجان شديد كان يتوقعه، لهذا قطع سبيل الجدال وأغلق باب النقاش بصرامة!

وقد ظللت أفكر في رد بليغ عليه، لهذا ذهبت إليه بعد انتهاء المحاضرة التالية، وقلت له:

-      هل تسمح لي بالكلام بلا حزازة يا دكتور؟

فسمح لي مشكورا، فقلت له من بين ضحكاتي إنني كتبت أغنية وأريد أن أسمعها له، فقال لي:

-      امسك نفسك وقل!

فقلت له:

-      برسيم المحبة خلص، وحمير الشوق جعانين

وعلف التلاقي غلي، وأنا أجيب فلوسه منين؟

فضحك قائلا:

-      أغنية جميلة، ولكن ما علاقة المحبة بالبرسيم؟

-      هذا تشبيه بليغ بإضافة المشبه به إلى المشبه.

-      لا تحاول خداعي.

-  لا أبدا.. هي هكذا في البلاغة فعلا.. ثم إن علاقة المحبة بالبرسيم، هي نفس علاقتها بالكوز :).. برسيم المحبة.. كوز المحبة.. فيتامين المحبة!!

فضحك قائلا:

-  لدينا منتدى أدبي هنا في الكلية يعقد أسبوعيا، وعليك أن تأتي.. وسأقول لك كلاما بيننا كشباب، أنا لا أستلطف كلمة اتخرم، وأراها غير لائقة.

شكرته على الدعوة وعلى صراحته، وتوقعت أنه سيحذف هذا المثال بعد ذلك من محاضراته، ولكن من حضروا محاضراته التالية، أكدوا لي أنه لم يفعل!

***

 

 

 


وحدة الذاكرة (البايت) Byte



وحدة الذاكرة (البايت) Byte:
كما نقيس المسافة بالمتر، والوزن بالجرام، فإن الذاكرة تقاس بالوحدة الثنائية المسماة Byte.. ويتكون كل Byte من 8 خانات ثنائية يسمى كل منها Bit. ويستطيع كل بت أن يحفظ إحدى القيمتين: 0 أو 1 .  

تعريف:
الوحدة الثنائية (البايت) Byte:
هي وحدة التخزين في ذاكرة الجهاز، ويمكن أن تحفظ عددا محصورا بين 0 و255.
 
الخانة الثنائية (البت) Bit:
هي أصغر وحدة تخزين متاحة في ذاكرة الحاسب، ويمكنها أن تحفظ إحدى القيمتين: صفر أو واحد.. وكل 8 خانات ثنائية تكون معا وحدة ذاكرة واحدة (بايت) Byte.. أي أن:
8 Bits = 1 Byte


ويختلف كل نوع من أنواع البيانات عن الآخر في عدد وحدات الذاكرة Bytes التي يحتاجها.. فالنص "محمود" مثلا يحتاج إلى 5 وحدات في الذاكرة (5 Bytes) لحفظه بالترميز القياسي ASCII، بينما الحرف "م" يحتاج إلى وحدتين في الذاكرة 2 Bytes لحفظه بالترميز الموسع Unicode. 

من كتاب المبرمج الصغير للصف الثالث الإعدادي (الفصل الدراسي الثاني).. للتنزيل كاملا:


الخميس، 16 فبراير، 2017

أنا وكرشي



أنا وكرشي
(قصيدة خرجت من كرش المعاناة)
 


بيني وبينَ الكرشِ ثأرٌ بائتٌ = وودتُ لو أني أخذتُ بثاري
لا يَرعوي يُلقي عليَّ مَلامةً = ويقولُ لي في ليلِهِ ونهاري:
أينَ الغَداءُ وما لَهُ مِن لذّةٍ = أينَ العَشاءُ ووجبةُ الإفطارِ؟
أينَ الثَّرِيدُ وقد تَطايرَ عِطرُهُ = مِثلَ النسيمِ لسائرِ الأقطارِ؟
هانتْ عليكَ الآنَ عِشرةُ عمرِنا = وشخيرُنا في ليلةِ الأسمارِ؟
إن لم يكُنْ للوُدِّ عِندَكَ بطّةٌ = فدجاجةٌ أو طائرُ الأطيارِ
أو ربعُ كيلو مِن كبابٍ إنّهُ = شافي الهمومِ وشاحذُ الأفكارِ
أو جُد بـ"بيتزا" أو فطيرٍ ساخنٍ = وكَفَى زمانُ بطاطسٍ وخُضارِ
أو ملبنٍ حلوٍ وبعضِ هريسةٍ = قد زِدتَ حِرماني بطعمِ مرارِ!

 

فهتفتُ: يا كذابُ تُنكِرُ أكلَنا = للعدسِ والكُشري وبعضِ ثمارِ؟
يا مُجرمًا أجريتَ ريقي، مدمنًا = للأكلِ بعدَ الأكلِ باستمرارِ
أفما كفاكَ بأن قتلْتَ رشاقتي = وكأنّني غولٌ حبيسُ الغارِ؟
وجعلتَني بينَ الوَرَى أضحوكةً = مِن فرطِ حجمٍ لافتِ الأنظارِ؟
حتى غدا الفِضفاضُ دونَ أناقةٍ = لِبْسي، أسيرُ ككاتمِ الأسرارِ!
أُخفيكَ عن عينِ الحِسانِ كأنني = أُخفي جَنينًا مُثقلاً بالعارِ!
فأجابَ: دَعْ عني حِسانَكَ إنّما = للفاتناتِ لديَّ طعمُ "الكاري"
وأنا وأنتَ وما أردنا ثالثًا = اثنانِ في عشقِ الطعامِ نُباري
فهتفتُ: يا إبليسُ فاخْرَسْ قبلَما = أجتازُ في التوبيخِ حدَّ وقاري
جاوزتَ حجمَكَ فانتفختَ تَكَبُّرًا = قد آنَ ردعُكَ والقرارُ قراري
فاقنعْ ببعضِ الجُبنِ هذا أكلُنا = والحُلوُ هذا اليومَ بعضُ خيارِ! 
محمد حمدي غانم
14/2/2017

 

 


DbDataRecord Class



 فئة سجل البيانات DbDataRecord Class 

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

من كتاب: من الصفر إلى الاحتراف برمجة قواعد البيانات في فيجوال بيزيك دوت نت ADO .NET.. للتنزيل:


الثلاثاء، 14 فبراير، 2017

حبك جنان



حبك جنان 



عارفة ليه حبك جنان؟

بمشي بين الناس بدندن غنوة باسمك بافتتان

بالورود ومشاعري برسم شِعري ليكي ع الحيطان

وانتظر يفتح لي ضحكك لما أخبط ع البيبان

وأما أقول على واحدة حلوة يبقى فيها حاجة منك مش عشان أنا ألعوبان

صعب أخون ف عنيكي قلبي، عمر حبك يوم ما هان

كل دا يا حبيبتي وأكتر نفسي أقوله من زمان

بس معرفش أما أشوفك بلقى نفسي ليه جبان؟!

محمد حمدي غانم
9/2/2017

 


الاثنين، 13 فبراير، 2017

تمثيل البيانات Data Representation




تمثيل البيانات Data Representation

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

ومهما كان نوع البيانات، ومهما كان حجمها، فإنها تحفظ في الذاكرة في صورة أرقام، لكن برنامجك يتعامل مع كل رقم بطريقة مختلفة تبعا لنوعه.. دعنا مثلا ننظر إلى العدد 255.. هذا العدد:
- يمثل الحرف ے في الترميز الأمريكي القياسي للحروف ASCII.
- ويمثل الحرف ÿ في الترميز العالمي الموسع للحروف Unicode.
- ويمثل اللون الأحمر لو أردت رسمه على الشاشة.
- ويمثل نغمة معينة لو أردت إخراجه من سماعة الجهاز.
- أما لو نظرت إلى هذا العدد باعتباره عددا صحيحا موجبا، فسيكون هو نفسه العدد 255 بدون تغيير، أما إذا اعتبرته عددا صحيحا سالبا، فسيمثل الرقم -127!

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


الجمعة، 10 فبراير، 2017

الرجل الذي غازل الرياضيات



الرجل الذي غازل الرياضيات:

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

وقد أفاجئكم بأن دكتور محمد قد قرأ من تراث الشعر العربي أكثر مما قرأت أنا كشاعر، لكنه لا يصنف نفسه كشاعر، رغم أن له عددا قليلا من المحاولات الشعرية القصيرة.. وقد فاجأني منذ عشرة أيام بهذا البيت الرائع:
جميلٌ أنتَ في كلِّ المرايا = رشيقُ القَدِّ في كلِّ الزوايا
الذي راوده أثناء انغماسه في قراءاته الرياضية المتعمقة.. والمدهش في الأمر أن د. محمد عطية في هذا البيت كان في أسمى تأملاته الفلسفية الرياضية.. فالشطرة "جميل أنتَ في كل المرايا" تمثل فكرة رياضية عميقة، وهي البحث عن دوال لا متغيرة تحت عدة تحويلات:
Invariant functions under specific transforms
أما الشطرة "رشيقُ القَدِّ في كلِّ الزوايا" فهي من الغزل الرياضي أيضا، لكن من باب هندسة المقاييس والأبعاد Geometry، كما أن فيها إحدى رؤى ميكانيا الكم!

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

وقد أضفت 10 أبيات، وأريتها له بالأمس، فأبدى رغبته في إضافات أخرى ومن خلال النقاش ولدت 7 أبيات أخرى، حتى خرجت هذه القصيدة في هذا الشكل، الذي نرجو أن يروق لكم:


 
 


IDataRecord Interface



 واجهة سجل البيانات IDataRecord Interface 

تقدم هذه الواجهة الخصائص والوسائل اللازمة لقراءة محتويات السجل الحالي في قارئ البيانات.
وتمتلك هذه الواجهة الخاصيتين التاليتين: 

* عدد الحقول FieldCount:
تعيد عدد الأعمدة في السجل.. هذا يتيح لك كتابة حلقة تكرار Loop للمرور عبر كل الأعمدة بدءا من العمود رقم صفر إلى العمود رقم FieldCount-1.. هذا مفيد لاختصار الكود عندما تستخدم استعلام يعيد عددا كبيرا من الحقول. 

* العنصر Item:
هذه هي الخاصية الافتراضية Default Property، وهي تستقبل رقم العمود أو اسمه كمعامل، وتعيد كائنا Object يحتوي على القيمة الموجودة في السجل الحالي في هذا العمود.. والمثال التالي يعرض قيمة الخانة الاولى في الصف:
MsgBox(Reader.Item(0))
أو باختصار:
MsgBox(Reader(0)) 

كما تمتلك هذه الواجهة الوسائل التالية: 


الأربعاء، 8 فبراير، 2017

ظلال من رؤاي



ظلالٌ مِن رُؤاي
مشاعرُ لا متغيرةٌ تحتَ عدةِ تحويلات
 
جميلٌ أنتَ في كلِّ المرايا = رشيقُ القَدِّ في كلِّ الزوايا

رقيقُ الهمسِ، مثلَ الضوءِ تَسرِي = إلى ما لا نهايةَ في نُهايَ

فيا بُرهانَ نبضي في شرودي = ويا موجاتِ صوتي في غِنايَ

إذا فاضلْتَ مِن شِعري شعوري = فَكَامِلْ بانضوائكَ مُنحنايَ

وكن للجُزءِ في مَعنايَ كلاًّ = وكن جزءا تَجذَّرَ في الحنايا

وألهمني سؤالا عن جوابٍ = لكونِكَ أنتَ مَبدا مُنتهايَ

أعاني فيكَ كَمْ لغزٍ خَفِيٍّ = ألا يرتاحُ قلبي يا ضَنايَ؟

سؤالٌ ظلَّ يَشغَفُني طويلاً = كبحثِ العارفينَ عن الخفايا

فأنتَ على دروبِ الحُلمِ شمسي = وأنتَ ظلالُ فكري في رُؤايَ

وفي ليلِ انطفائي أنتَ بدري = وأنتَ سراجُ فَرْحي في شَقايَ

***

فَمَنْ أختارُ؟.. قُلْ لي يا هوايَ = سرقتَ السحرَ مِن كلِّ الصبايا

فلا تعتبْ على قلبي، أنا لا = أريدُ سواكَ مِن بينِ البرايا

أنا في العشقِ لا أبغي كثيرا = فحسْبي بسمةٌ أحلى الهدايا

وأَتبِعْ بسمةً أخرى بأخرى = مباحٌ منكَ سَلسالُ العطايا

كثيرٌ منكَ يا عمري قليلٌ = فهَبْ لي ألفَ نَجمٍ يا سَمايَ

هيَ الأكوانُ والأزمانُ فينا = ولا معنى لِعُمرِكَ مِن سوايَ

ولا حسنٌ إذا فارقتَ عيني = ولا قلبي بشِعرِكَ صارَ نايا

تعالَ ابدأ حياتَكَ في حياتي = وذُبْ حتى فنائِكَ في فَنايَ

د. محمد عطية العربي

م. محمد حمدي غانم

8/2/2017


قارئ البيانات DataReader



قارئ البيانات DataReader: 

يتم إنشاء قارئ البيانات DataReader باستدعاء الوسيلة ExecuteReader الخاصة بكائن الأمر Command Object.. ويستقبل قارئ البيانات نتيجة الاستعلام الذي ينفذه كائن الأمر، ويقوم بتخزين ما يصل من البيانات من الخادم في المخزن الوسيط للشبكة Network Buffer الموجود على جهاز العميل، حيث يمكنك المرور عبر السجلات المستلمة واحدًا تلو الآخر على التوالي، وهو ما يوفر ميزتين هامتين:
1- السرعة: حيث يمكنك قراءة السجلات المتوفرة فور وصولها، دون انتظار اكتمال وصول كل السجلات أولا.
2- عدم استهلاك الذاكرة: لأن قارئ البيانات يحتفظ بسجل واحد فقط في الذاكرة في كل مرة.
لكنّ لهذه الطريقة عيبين أساسيين:
1- عدم القدرة على تحديث سجلات قاعدة البيانات.. بعبارة أخرى: قارئ البيانات للقراءة فقط كما يقول اسمه، وليس للكتابة!
2- عدم القدرة على التراجع إلى الخلف، أو القفز مباشرة إلى سجل في موضع معين في النتيجة دون المرور على ما قبله من السجلات.
لهذا يوصف قارئ البيانات بأنه "مجرى بيانات للأمام فقط وللقراءة فقط":
Forward-only, Read-only Stream.

لكل هذا، يمكنك استخدام قارئ البيانات في الحالات التالية:
1- لو كنت ستتعامل مع سجلّ واحد فقط.
2- لو كنت ستقرأ كل سجل مرة واحدة فقط، ولا يعنيك الرجوع إليه مرة أخرى.
3- لو كانت قاعدة البيانات موجودة على نفس الجهاز، ما يعني سرعة الحصول على البيانات منها مباشرة، دون الحاجة إلى تحميلها في الذاكرة.
4- عندما تريد قراءة النتائج دون الحاجة إلى تغيير أي جزء منها في قاعدة البيانات.

وسنتعرف في المواضيع التالية على فئات ADO.NET التي تتيح لك التعامل مع قارئ البيانات.
 
من كتاب: من الصفر إلى الاحتراف برمجة قواعد البيانات في فيجوال بيزيك دوت نت ADO .NET.. للتنزيل:


الاثنين، 6 فبراير، 2017

قلب خالي



قلب خالي 

عاينتُ صدري بالصدى، فوجدتُ قلبي خاليا
ترتجُّ في حجراتِه أصداءُ نبضي عاليا
فهتفتُ ذعرًا بالطبيبِ وقلتُ: ويحي ما لِيَ؟
أينَ الحبيبةُ؟.. خِلتُها في القلبِ، تسكنُ بالِيَ!
فأجابني: فلتنسَ شِعرَك ها هنا مُستَرخِيَا
هذا فؤادُكَ فارغًا يحتاجُ قلبا حانيا
حتى يدقَّ برقةٍ ويذوقَ عيشا هانيا
والشِّعرُ يا دكتورُ؟.. صاحَ بغضبةٍ: يا غاويا
ما أكذبَ الشعراءَ يَهوَونَ الكلامَ الخاويا!
بل يعشقونَ خيالَهم مُتَجرِّدًا مُتَعاليا
ويصدقون جنونَهم كالغِرِّ يَمشي هاذيا
فأجبتُ في خجلٍ: صدقتَ وذاكَ فعلا حاليَ!
الطبُّ زادكَ حكمةً، قد صرتَ مثلَ الأوليا!
فامنحْ لدائي وصفةً واكتبْ دواءً شافيا
"الحلُّ سهلٌ" قال لي "تحتاج حبا صافيا"
حبا أصيلا واقعيا لا خيالا واهيا
فأجبت في تنهيدة: أدرجتَ صِنفًا غاليا
أفلا بديلَ؟.. أجابَ: لا.. أعطيكَ قولا ناهيا
الحبُّ ليس قصيدةً تشدو بها متباهيا
الحبُّ أسرارٌ بقلبِكَ لستَ تدري ما هيَ
فأجبتُ في خجلٍ: صدقتَ، أبنتَ أمرا خافيا
شكرا طبيبي قد أنرتَ الدرب لي متراميا
فغدا أرومُ حبيبةً وأقولُ شعرا ثانيا

:D :D :D

 

محمد حمدي غانم
4/2/2017

__________

عاينت قلبي بالصدى (إيكو Echo).. فحص القلب بالموجات فوق الصوتية.. شكر خاص لصيدقي العزيز دكتور طارق سالم استشاري أمراض القلب.
عيادة د. طارق محمود سالم في مدينة فارسكور:
بجوار موقف فارسكور.
عيادة د. طارق محمود سالم في مدينة دمياط:شارع البندر، أمام موقف المنصورة، أعلى صيدلية د. شريف.. هاتف: 2349134
 


UPDATE .WRITE



التحرير المتتابع للسجلات، باستخدام الأمر UPDATE .WRITE:

عند التعامل مع أعمدة تحتوي على بيانات من النوع text أو ntext أو image في سيكيويل سيرفر 2000، كانت تواجهنا مشكلة خطيرة، وهي كيفية إرسال كم ضخم من البيانات من العميل إلى الخادم لحفظه في هذه الأعمدة.. افرض أنك تريد وضع صورة حجمها 10 ميجا في خانة من النوع image بالاستعلام التالي:

UPDATE Publishers

SET Logo = @Logo

WHERE ID = 1

حيث @Logo هو معامل من النوع image يحمل بيانات الصورة.. لو حاولت تنفيذ هذا الاستعلام، فسيستغرق إرسال الصورة إلى الخادم وقتا ملموسا (تبعا لسرعة الاتصال، وحجم العبء على الخادم في تلك اللحظة)، وقد يتعطل برنامجك عن الاستجابة، وقد ينفد وقت الانتظار Timeout قبل إتمام العملية.

ويمكنك أن تجرب الاستعلام السابق بضغط الزر Add Logo في المشروع WriteLargeData.. جرب اختيار صورة حجمها كبير لترى تأثير هذا.

وللأسف، لا يفيدك استخدام استعلام كالتالي:

UPDATE Publishers

SET Logo = Logo + @Logo

WHERE ID = 1

هذا الاستعلام يحاول إضافة جزء من بيانات الصورة موضوع في المعامل @Logo إلى البيانات الموجودة فعليا في عمود الصورة Logo.. لكن للأسف، سيؤدي هذا إلى حدوث خطأ، لأن سيكويل سيرفر لا يعرف كيف يجمع بيانات من النوع image !

ولحل هذه المشكلة، قدمت سيكويل سيرفر 2005 الأنواع القصوى الجديدة varchar(max), nvarchar(max), varbinary(max) وهي مخصصة للتعامل مع الكائنات الثنائية الضخمة Binary Large Objects (BLOBs)، فهي تستطيع استقبال بيانات يصل حجمها إلى حوالي 2 جيجا بايت، كما يمكنها التعامل مع البيانات الثنائية والحروف بطريقة تتابعية Sequential، أي أنك تستطيع الكتابة فيها في أي موضع، أو القراءة منها من أي موضع.

لهذا إذا كنت تنوي التعامل مع بيانات ضخمة BLOBs، فالأفضل أن تستخدم:

- النـوع varchar(max) بـدلا من النوع Text.

- والنوع nvarchar(max)  بدلا من النوع ntext.

- والنوع varbinary(max) بدلا من النوع image.

وللكتابة التتابعية في هذه الأنواع الجديدة، قدمت T-SQL الصيغة الجديدة التالية لأمر التحديث:

UPDATE اسم_الجدول

SET اسم_العمود   .WRITE (@Value, @Offset, @Length )

Where شرط

فالدالة الداخلية Write تكتب البيانات المرسلة إلى المعامل @Value في الخانة المحددة في العمود، بدءا من الموضع @Offset، وبحيث يكون طول البيانات المكتوبة @Length.. لاحظ ما يلي:

- هذه الصيغة ستسبب خطأ إذا حاولت التعامل مع أي نوع بيانات غير الأنواع القصوى التي تنتهي بـ (MAX).

- هذه الصيغة ستسبب خطأ إذا حاولت إضافة بيانات في خانة قيمتها Null.. لهذا أمامك حلان:

1- إما أن تضيف الجزء الأول من البيانات باستخدام الصيغة العادية للأمر Update، ثم تضيف باقي أجزاء البيانات باستخدام الصيغة Update.Write .

2- وإما أن تمنع استخدام القيمة Null في خانات العمود، وفي هذه الحالة عليك استخدام قيمة افتراضية لوضعها في الخانات الفارغة، وذلك بوضع القيمة صفر في الخاصية Default Value Or Binding في خصائص العمود.. ولكي لا تؤثر هذه القيمة الافتراضية على القيمة التي ستضعها في خانات العمود، يجب أن تكون للمعامل @Offset القيمة صفر عند كتابة أول جزء من البيانات، لتوضع في بداية الخانة بدلا من أية بيانات موجودة.

- إذا أرسلت إلى المعامل @Value القيمة Null، فسيتم تجاهل المعامل @Length، وسيتم حذف القيمة الموجودة في الخانة في الموضع المحدد في المعامل @Offset.

- إذا أرسلت إلى المعامل @Offset القيمة Null، فسيتم تجاهل المعامل @Length، وستضاف قيمة المعامل @Value إلى نهاية البيانات الموجودة حاليا في الخانة.

- إذا أرسلت إلى المعامل @Offset قيمة أكبر من طول البيانات الموجودة في الخانة، فسيحدث خطأ.. ولكي تكتب بعد نهاية البيانات الموجودة، يجب أن ترسل إلى المعامل @Offset قيمة تساوي طول البيانات الموجودة في الخانة، أو ترسل إليه القيمة Null كما أوضحنا في الملحوظة السابقة.

- إذا أرسلت إلى المعامل @Length القيمة Null، فسيتم حذف جميع البيانات التالية للموضع المحدد في المعامل @Offset.

وستجد مثالا لاستخدام هذه الصيغة لكتابة بيانات صورة أول ناشر في العمود Logo2 في الجدول Publishers بطريقة تتابعية، وذلك في الزر Update .Write في المشروع WriteLargeData، وفيه نستخدم الاستعلام:

UPDATE Publishers

SET Logo2  .WRITE (@Logo, @Offset , @Length)

WHERE ID = 1

لاحظ أن العمود Logo2 من النوع varbinary(MAX)، وأن قيمته الافتراضية هي 0.. ولكتابة بيانات الصورة في الخانة الأولى من هذا العمود تتابعيا، سنرسل أول 100 وحدة ثنائية Byte لحفظها في الخانة بدءا من الموضع رقم صفر، ثم نرسل 100 وحدة تالية لحفظها في الخانة بدءا من الموضع رقم 100، ونستمر في فعل هذا إلى أن ننتهي من كتابة بيانات الصورة.. هذا معناه أننا سنستخدم الاستعلام Update .Write عدة مرات (وذلك من خلال حلقة تكرار Loop)، لكن مع تغيير المعاملات المرسلة إلى الدالة الداخلية .Write في كل مرة.. طبعا إرسال 100 وحدة ثنائية في كل مرة، أفضل بكثير من إرسال 10 ميجا أو أكثر دفعة واحدة.. لكن هذا قد يصير عبئا خطيرا على البرنامج إذا كانت الصورة ضخمة جدا، بسبب زيادة عدد مرات إرسال البيانات من العميل إلى الخادم.. لهذا عليك اختيار حجم مناسب لأجزاء البيانات التي ترسلها، بحيث لا يكون كبيرا جدا فيدمر الذاكرة ويبطئ عملية الإرسال، ولا يكون صغيرا جدا فيؤدي إلى إضاعة وقت كبير من الخادم بسبب كثرة عدد الأوامر المرسلة إليه من عميل واحد.. ربما يكون الأنسب مثلا أن تستخدم 1024 وحدة ثنائية (1 كيلو بايت) لكل جزء.. لكن هذا سيجعلك ترسل الصورة التي حجمها 1 ميجا فقط على حوالي 1000 مرة.. ما زال هذا يبدو كثيرا.. أليس كذلك؟.. لو شئت رأيي، فإن إرسال 100 كيلو في كل مرة سيكون مناسبا، فهذا سيرسل الصورة التي حجمها 1 ميجا باستخدام 10 أوامر فقط وهذا ليس كثيرا، كما أن 100 كيلو ليس بالحجم المقلق الذي يستغرق وقتا ملموسا عند إرساله إلى الخادم.. لكن عليك في هذه الحالة أن تجعل للخاصية Timeout الخاصة بالاتصال الذي تستخدمه قيمة أكبر قليلا، ولتكن 120 ثانية على سبيل الاحتياط.. وسنعرف كيف نفعل هذا لاحقا عند دراسة كائن الاتصال وكائن الأمر.

 

ملحوظة:
الإصدارات القديمة من T-SQL، كانت تستخدم الأوامر UPDATETEXT و READTEXT و WRITETEXT للتعامل مع البيانات الضخمة الموجودة في الأعمدة من النوع image أو text أو ntext.. لكن لا ينصح باستخدام هذه الأوامر الآن لأنها ستزال من لغة الاستعلام، وبدلا من هذا عليك استخدام الأنواع القصوى، والصيغة Update .Write.

 

من كتاب: من الصفر إلى الاحتراف برمجة قواعد البيانات في فيجوال بيزيك دوت نت ADO .NET.. للتنزيل:


 


صفحة الشاعر