المؤشرات في الـ Sql Server
________________________________
بسم الله الرحمن الرحيم :
سنبدأ اليوم بإذن الله دروس عن المؤشرات في الـ T-SQL اللغة البرمجية في الـ Sql Server .
ولكن بداية دعوني أمهّد للموضوع :
فما هي المؤشرات و ما تفيدنا كمبرمجين في قواعد البيانات Sql Server ؟؟
هذه المؤشرات هي عبارة عن Record Set مجموعة سجلات شبيهه بتلك التي نستخدمها بالـ VBA ..
والتي من خلالها نقوم بالتنقل خلال السجلات ( التالي و السابق و الأول و الأخير ) ..
ربما ستسأل نفسك ما الفائدة من هذه المؤشرات طالما أن الاستعلامات تقدم لي كل ما أحتاج ..؟؟؟
سأجيبك بالقول إن الاستعلامات لها أوجه قصور في بعض النواحي و ستتضح لديك هذه الأوجه في
الأمثلة التي سنسردها ... فلا تبدأ بالتململ لأن الدرس سيكون بمعلوماته رائع و مفيد جداً جداً لمن لا
يعرف ما هي المؤشرات ..
المؤشرات تسمح لك بالمرور على كل سجل من مجموعة سجلات المؤشر و تنجز عليه العمليات التي تحتاجها ..
كأن تجلب لكل فاتورة تفاصيلها (التي هي عبارة عن مجموعة من سجلات جدول آخر) ..
ولكن كيف سنعرف مؤشر جديد أو بالأحرى كيف أبدأ ببرمجة مؤشر و التعامل معه .. ؟
باختصار أقول لك الأمثلة سترويك تماماً :::::
عليك أولاً :
1- أن تصرح عن مؤشر .
2- تفتح المؤشر .
3- جلب سجلات . ( التالي , السابق , الأول , الأخير , السجلات (n) بعد السجل الحالي ,
السجل ذو الترتيب (n) ) ..
4- إغلاق المؤشر .
5 - إزالة المؤشر من الذاكرة .
للمؤشر صيغتان : قياسية (SQL-92) .. و الأخرى التي تستخدم كامل توسعات اللغة T-SQL .
التصريح عن المؤشر :
الصيغة القواعدية للمؤشر من النوع القياسي :
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
الصيغة الموسعة للمؤشر ( التي سنفصلها لاحقاً بإذن الله ) كالتالي :
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ] [ FORWARD_ONLY | SCROLL ] [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ] FOR select_statement [ FOR UPDATE [ OF column_name [ ,...n ] ] ]
ما أرجوه منك الآن هو ألا تخاف من هذا الكود لأنك ستجد كم هو سهل بعد أن تقرأ الشروحات التالية ..
سأبدأ بالصيغة القياسية :
Declare :
و هي تستخدم للتصريح عن متحولات كما تعلم ..
cursor_name :
و هو اسم اختياري يضعه المبرمج للمؤشر للإشارة إليه ضمن الكود ,
و عليك أن تنتبه أخي الكريم إلى ن هذا الاسم يتبع لقوانين تسمية المتحولات في الـ T-SQL ..
INSENSITIVE :
1.تجعل المؤشر للقراءة فقط أي غير قابل لاستخدام العبارة Where Current Of
معه في عبارات الحذف و التعديل ..
( أما عن هذه العبارة فلا تكن عجولاً و لا تحرق المراحل ستعرف لاحقاً ما المقصود منها )
ولكن لماذا ؟
الإجابة : لأنها تنشئ نسخة مؤقتة من بيانات المؤشر ليستخدمها المؤشر ..
أي أن بيانات المؤشر قد لا تكون بالضرورة نفس بيانات المصدر عند استخدام العبارة
(INSENSITIVE) في تصريح المؤشر من النوع القياسي ..
و بالتالي ستتوصل إلى نتيجة بسيطة ( في هذه الحالة ) و هي عندما تعدل سجلات مصدر البيانات
الذي يعتمد عليه المؤشر (أي مجموعة السجلات أو الجدول الذي يأخذ منه المؤشر بياناته ) فلن
ينعكس ذلك على السجلات التي يجلبها المؤشر لأنه يأخذ من النسخة المؤقتة كما أسلفت .
مثال 1 : أنشأ بداية قاعدة بيانات للأمثلة و ليكن اسمها Test_DB و اقرأ المثال التالي بهدوء
سيصعب عليك فهم بعض الأمور لكنك سرعان ما ستحصل على زبدة الكلام هذا بفضل
صبرك و ذكائك .. فلا تستعجل .
use Test_DB Go -- إنشاء جدول لنستخدمه في المؤشرات Create Table C( id int , name nvarchar(50) ) Go -- إدخال بعض القيم فيه Insert C Values (1, 'Hmeed') Insert C Values (2, 'Smeer') Insert C Values (3, 'Aamer') Insert C Values (4, 'Sheeren') Insert C Values (5, 'Abdo') Go -- التحقق من إدخال البيانات Select * From C ------------------------------------ -- التصريح عن مؤشر عادي و قياسي Declare A Cursor For Select * From C -- فتح المؤشر لجلب البيانات منه Open A -- جلب السجل الأول Fetch Next A -- سنعدل في السجل الثاني و سنرى كيف سينعكس ذلك على بيانات المؤشر Update C Set Name = 'وليد' Where id = 2 -- ستجد أن المؤشر قد جلب البيانات المحدثة جلب السجل الذي قمت بتعديله بالعبارة السابقة Fetch Next A -- هل شاهدت السجل الذي عدلت بياناته Select * From C -- إغلاق المؤشر Close A -- تحرير بيانات المؤشر DeAllocate A
------------------------------------
في المثال التالي :
-- لا تنعكس التعديلات على بيانات الجدول في المؤشر
-- التصريح عن مؤشر قياسي لكن غير حساس للتعديلات
-- (لأنه يتعامل مع نسخة من بيانات الجدول وليس مع الجدول نفسه )
Declare A Insensitive Cursor For Select * From C Open A Fetch A Update C Set Name = 'For You' Where id = 2 Fetch A Close A DeAllocate A Select * From C
------------------------------------
Scroll :
تجعل المؤشر يقبل كافة أنواع جلب السجلات (التالي , السابق , الأول , الأخير ,
Absolute , القريب) .. ستتعرف إلى كلٍ على حدى .
إذا لم نحدد هذا الخيار للمؤشر فإنه لن يقبل إلا الانتقال إلى السجل التالي بالعبارة Fetch ..
كما استخدمنا التعليمة Fetch في المثال السابق ..
select_statement :
ألا و هي كما تلاحظ أخي الكريم عبارة استعلام قياسية تعيد مجموعة من
السجلات RowSet ..
READ ONLY :
تمنع هذه العبارة استخدام العبارة Where Current Of للمؤشر
مع عبارات التعديل و الحذف .. الآن سأشرح لك ما المقصود بهذه العبارة
و كيف يتم استخدامها ...
مثال 2 : على استخدام العبارة Where Current Of للمؤشر ..
Declare A Cursor For Select * From C For Update Open A Fetch A -- كالتالي C تقوم هذه العبارة بتعديل السجل الحالي للمؤشر في الجدول Update C Set Name = 'For You' Where Current Of A Fetch A -- تقوم هذه العبارة بحذف السجل الذي جلبه السطر السابق Delete From C Where Current Of A -- شاهد التعديلات التي حصلت على سجلات الجدول المستهدف من قبل المؤشر Select * From C Close A DeAllocate A
في الحقيقة الذي يجعل المؤشر للقراءة فقط في النوع القياسي من المؤشرات هو إحدى ثلاث أمور وهي:
1. أن يكون غير حساس ... أي Insensitive .. وقد سبق توضيح معناها .
2. أن يكون من النوع Scroll قابل للحركة في كافة الاتجاهات (سابق , تالي , أول , أخير .. الخ )
3. أن يكون للقراءة فقط Read Only ..
سنضرب ( بالعصا طبعاً ) الأمثلة التالية : أريدك ألا تحزن على هذه الأمثلة لأنها تستحق الضرب ..
مثال 3 :
لو أخذنا المثال السابق و وضعنا السطر التالي :
Declare A Scroll Cursor For Select * From C For Update عوضاُ عن السطر : Declare A Cursor For Select * From C For Update
ثم قمنا بتنفيذ المثال .. ماذا سيحصل ؟؟
سيعطيك المفسر رسالة خطأ تفيد بأن العبارة For Update لا تأتي مع المؤشرات من
نوعRead Only ... ذلك لأنك وضعت العبارة Scroll لتصريح المؤشر ..
مثال 4 : بنفس الطريقة لو وضعنا العبارة Insensitive لتصريح المؤشر كالتالي :
Declare A Insensitive Cursor For Select * From C For Update
أيضاً سيعطيك المفسر رسالة خطأ تفيد بأن العبارة For Update بأن العبارتين For Update و Insensitive
لا تجتمعان و بذلك عطلت Insensitive إمكانية التعديل للبيانات المؤشر ...
ارجع إلى الشرح السابق للخيار Insensitive لتعرف أكثر ما هو السبب .!!
مثال 5 : وضع الخيار Read Only For :
Declare A Cursor For Select * From C For Read Only
UPDATE [OF column_name [,...n]] :
هذا الخيار يسمح لك بجعل المؤشر يقبل حذف أو تعديل
سجله الحالي شرط ألا يكون هذا المؤشر للقراءة فقط كما ذكرنا للتو ..
أيضاً تمكنك هذه العبارة من تحديد الحقول التي سوف يسمح بتعديل قيمها عن طريق المؤشر
بعبارة الـ Update ..
و إذا بدون تحديد حقول ( باستخدام OF ) فهذا معناه أن كافة الحقول يسمح بتعديلها في السجل الحالي للمؤشر ..
مثال 6 :
-- Id التعديل مسموح فقط لقيم الحقل Declare A Cursor For Select * From C For Update OF id Open A Fetch A -- للسجل الحالي من المؤشرName لن تستطيع العبارة التالية تعديل بيانات الحقل Update C Set Name = 'T-SQL Is My Friend' Where Current Of A Select * From C Close A DeAllocate A
مثال 7 : أما في هذا المثال ستتمكن من تعديل قيمة الحقل Name و ذلك لأننا حددنا الحقل Name
من المؤشر على أنه قابل للتعديل عن طريق العبارة Where Current Of ..
Declare A Cursor For Select * From C For Update OF Name Open A Fetch A -- للسجل الحالي من المؤشرName تستطيع العبارة التالية تعديل بيانات الحقل Update C Set Name = 'T-SQL Is My Friend' Where Current Of A Select * From C Close A DeAllocate A
مثال 8 :أيضاُ في هذا المثال ستتمكن من تعديل قيمة الحقل Name و أي حقل من الجدول الذي
يستخدمه المؤشر كمصدر للبيانات وذلك لأننا لم نحدد أي عمود للعبارة For Update ..
Declare A Cursor For Select * From C For Update
و بذلك نكون قد أنهينا بعون الله الدرس الأول عن المؤشرات ..
لقاؤنا يتجدد في الدرس القادم بإذن الله ..
أخوكم في الله عماد ..