بشكل أو بآخر، قمنا بإنشاء قوائم ذات مستويين أو ثلاثة مستويات مثل أدلة الشجرة وتصنيفات المنتجات. إذا واجهنا المزيد من مستويات التصنيف، فإننا نستخدم التكرار بشكل عام. سيؤدي استخدام العودية في البرنامج إلى زيادة بعض حملات الأداء بشكل أو بآخر.
لقد استخدمت ASP.net لتنفيذ دليل تصنيف غير محدود المستوى في البرنامج من قبل، ولكن نظرًا لأن قابلية النقل ليست قوية، فقد قمت بتغييره إلى إجراء مخزن وأرسلته للجميع للدراسة معًا حتى الآن. أثناء عملية الاختبار، لم يتم العثور على أي مشاكل، بالإضافة إلى ذلك، لم يتم تحسين الكود.
عادةً ما تكون معظم عملياتنا هي قراءة الدلائل، لذلك في التنفيذ التالي، نحتاج فقط إلى عبارة تحديد واحدة للقراءة، بدون التكرار، المستوى لا نهائي من الناحية النظرية ~!
================================================================================================== ============================================================================
هيكل الجدول:
اسم الجدول: Tb_Column
بنية الجدول (جميع الحقول غير فارغة):
Column_ID int المفتاح الأساسي (ملاحظة: غير معرف)
Column_Name nvarchar(50) اسم التصنيف
Parent_ID int معرف فئة الأصل (القيمة الافتراضية 0)
مسار تصنيف Column_Path nvarchar(1000).
عمق تصنيف Column_Depth int (القيمة الافتراضية 0)
فرز Column_Order int (الافتراضي 0)
وصف تصنيف Column_Intro nvarchar(1000)
============================= === ========================================================
الإجراء المخزن الأول: إنشاء تصنيف جديد
CREATE PROCEDURE sp_Column_Insert
(
@Parent_ID int،
@Column_Name nvarchar(50)،
@Column_Intro nvarchar(1000)
)
مثل
قم بتعريف @Err كـ int
اضبط @Err=0
ابدأ النقل
--احصل على معرف العمود من السجلات الموجودة
قم بتعريف @Column_ID كـ int
قم بتعريف @Column_Depth كـ int
حدد @Column_ID = Max(Column_ID) من Tb_Column
إذا لم يكن @Column_ID فارغًا
قم بتعيين @Column_ID = @Column_ID+1
آخر
قم بتعيين @Column_ID = 1
- حدد ما إذا كان عمود المستوى الأعلى وقم بتعيين Column_Path وColumn_Order الخاص به
قم بتعريف @Column_Path كـ nvarchar(1000)
قم بتعريف @Column_Order كـ int
إذا @Parent_ID = 0
يبدأ
اضبط @Column_Path =Ltrim(Str(@Column_ID))
حدد @Column_Order = Max(Column_Order) من Tb_Column
إذا لم يكنColumn_Order فارغًا
اضبط @Column_Order = @Column_Order + 1
آخر--إذا لم يتم العثور على سجل، فهذا يعني أن هذا هو السجل الأول
اضبط @Column_Order = 1
--Depth
اضبط @Column_Depth = 1
نهاية
آخر
يبدأ
- احصل على مسار وعمق العقدة الأصلية
حدد @Column_Path = Column_Path ,@Column_Depth = Column_Depth من Tb_Column حيث
Column_ID=@Parent_ID
إذا كان @Column_Path فارغًا
يبدأ
تعيين @Err = 1
اذهب إلى النهاية
End
- احصل على الحد الأقصى لرقم التسلسل ضمن نفس العقدة الأصلية
حدد @Column_Order = Max(Column_Order) من Tb_PicColumn حيث Column_Path مثل
''+@Column_Path+'|%' أو Column_ID = @Parent_ID
إذا لم يكن @Column_Order فارغًا --إذا كان الرقم التسلسلي موجودًا، فقم بإضافة 1 إلى كافة أرقام التسلسل بعد الرقم التسلسلي
يبدأ
- تحديث الأرقام التسلسلية لجميع العقد بعد العقدة الحالية المراد إدراجها
تحديث مجموعة Tb_Column Column_Order = Column_Order +1 حيث Column_Order
>@Column_Order
- الحد الأقصى لرقم التسلسل ضمن نفس العقدة الأصلية بالإضافة إلى 1 يشكل رقم التسلسل الخاص به
اضبط @Column_Order = @Column_Order + 1
نهاية
آخر
يبدأ
اضبط @Err=1
اذهب إلى النهاية
النهاية
- يشكل مسار العقدة الأصلية بالإضافة إلى رقم المعرف الخاص بها مسارًا خاصًا بها
اضبط @Column_Path = @Column_Path + '|' + Ltrim(Str(@Column_ID))
--Depth
تعيين @Column_Depth = @Column_Depth+1
End
Insert In To Tb_Column(Column_ID,Column_Name,Parent_ID,Column_Path,
Column_Depth,Column_Order,Column_Intro) القيم (@Column_ID,@Column_Name,@Parent_ID,@Column_Path,@Column_Depth,@Column _الطلب،@Column_Intro )
إذا @@خطأ<>0
يبدأ
اضبط @Err=1
اذهب إلى النهاية
النهاية
- تحديث ترتيب السجل بعد السجل الحالي
- تحديث مجموعة Tb_Column Column_Order = Column_Order+1 حيث Column_Order> @Column_Order
theEnd:
إذا @Err=0
يبدأ
ارتكاب ترانس
العودة @Column_ID
نهاية
آخر
يبدأ
التراجع تران
العودة 0
نهاية
اذهب
====================================================================================== =====================
الإجراء المخزن الثاني: حذف الفئة
إنشاء الإجراء sp_Column_Delete
(
@Column_ID int
)
مثل
قم بتعريف @Err كـ int
تعيين @Err = 0
ابدأ تران
--تحقق أولاً مما إذا كانت هناك عقد فرعية أسفل العقدة
حدد Column_ID من Tb_Column حيث Parent_ID = @Column_ID
إذا @@RowCount<>0
يبدأ
تعيين @Err = 1
اذهب إلى النهاية
النهاية
- احصل على Column_Order للعقدة لفرز ترتيب السجلات الأخرى بعد الحذف
قم بتعريف @Column_Order كـ int
حدد @Column_Order = Column_Order من Tb_Column حيث Column_ID = @Column_ID
إذا كان @Column_Order فارغًا
يبدأ
اضبط @Err =2
اذهب إلى النهاية
النهاية
- تحديث Column_Order للسجلات الأخرى
تحديث مجموعة Tb_Column Column_Order = Column_Order -1 حيث Column_Order>@Column_Order
إذا @@ خطأ<>0
يبدأ
اضبط @Err =3
اذهب إلى النهاية
إنهاء
- حذف العملية
احذف من Tb_Column حيث Column_ID=@Column_ID
إذا @@ خطأ<>0
يبدأ
اضبط @Err =4
اذهب إلى النهاية
النهاية
- قم بتحديث Column_ID للسجلات الأخرى
- تحديث مجموعة Tb_Column Column_ID= Column_ID - 1 حيث Column_ID >@Column_ID
--إذا @@خطأ<>0
-- يبدأ
- اضبط @Err =5
- اذهب إلى النهاية
-- نهاية النهاية
:
إذا @Err = 0
يبدأ
ارتكاب ترانس
العودة 0 --حذف بنجاح
نهاية
آخر
يبدأ
إذا @ خطأ = 1
يبدأ
التراجع تران
العودة 1 - لديها العقد الفرعية
نهاية
آخر
يبدأ
التراجع تران
العودة 2--خطأ غير معروف
نهاية
نهاية
يذهب
================================================================================================== ===============
الإجراء المخزن الثالث: تحرير التصنيف
إنشاء الإجراء sp_Column_Update
(
@Column_ID int،
@Parent_ID int،
@Column_Name nvarchar(50)،
@Column_Intro nvarchar(1000)
)
مثل
قم بتعريف @Err كـ int
Set @Err=0
Begin Tran
- احصل على القيم قبل التعديل: Parent_ID، Column_Depth، Column_Order
قم بتعريف @oParent_ID كـ int
قم بتعريف @oColumn_Depth كـ int
قم بتعريف @oColumn_Order كـ int
قم بتعريف @oColumn_Path كـ nvarchar(1000)
حدد @oParent_ID = Parent_ID، @oColumn_Depth = Column_Depth،@oColumn_Order = Column_Order، @oColumn_Path = Column_Path من Tb_Column حيث Column_ID = @Column_ID
إذا كان @oParent_ID فارغًا
يبدأ
تعيين @Err = 1
اذهب إلى النهاية
النهاية
- إذا لم يتغير المعرف الأصلي، فقم بتعديل اسم العمود ومقدمة العمود مباشرةً.
إذا @oParent_ID = @Parent_ID
يبدأ
تحديث مجموعة Tb_Column Column_Name =Column_Name،Column_Intro =Column_Intro حيث Column_ID =Column_ID
إذا @@ خطأ <> 0
تعيين @Err = 2
اذهب إلى النهاية
نهاية
قم بتعريف @nColumn_Path كـ nvarchar(1000)
قم بتعريف @nColumn_Depth كـ int
قم بتعريف @nColumn_Order كـ int
- احصل على عدد العقد الموجودة في العقدة الحالية باعتبارها العقدة الأصلية [بما في ذلك نفسها] ملاحظة: إذا تم إرجاع "1"، فهذا يعني أنها عقدة واحدة
قم بتعريف @theCount كـ int
حدد @theCount = Count(Column_ID) من Tb_Column حيث Column_ID=@Column_ID أو Column_Path مثل ''+@oColumn_Path+'|%'
إذا كان @theCount فارغًا
يبدأ
تعيين @Err = 3
اذهب إلى النهاية
End
IF @Parent_ID=0 --إذا تم تعيينها كعقدة ذات مستوى أعلى، فقم بتعيين العقدة على آخر عقدة ذات مستوى أعلى
يبدأ
--طباعة "تعيين كعمود المستوى الأعلى"
تعيين @nColumn_Path = Ltrim(Str(@Column_ID))
تعيين @nColumn_Depth =1
حدد @nColumn_Order = الحد الأقصى (Column_Order) من Tb_Column
إذا كان @nColumn_Order فارغًا
يبدأ
تعيين @Err = 4
اذهب إلى النهاية
النهاية
@nColumn_Order = @nColumn_Order - @theCount + 1
- تحديث ثلاثة أجزاء 1 العقدة نفسها 2 جميع العقد الفرعية 2 ترتيب السجلات اللاحقة قبل أن تتغير هذه الشجرة
- طباعة "تحديث كافة الأعمدة بعد الموضع السابق لهذا العمود [باستثناء الأعمدة الفرعية ضمن هذا العمود]: Column_Order"
تحديث مجموعة Tb_Column Column_Order = Column_Order-@theCount حيث (Column_Order >@oColumn_Order) و (Column_Path ليس مثل ''+@oColumn_Path+'|%' )
إذا @@ خطأ <> 0
يبدأ
اضبط @Err = 7
اذهب إلى النهاية
إنهاء
- طباعة "تحديث هذا العمود: Parent_ID، Column_Path، Column_Depth، Column_Order، Column_Name، Column_Intro"
طباعة "الطلب:"+Ltrim(Str(@nColumn_Order))
تحديث مجموعة Tb_Column Parent_ID=@Parent_ID,Column_Path = @nColumn_Path,Column_Depth = @nColumn_Depth,Column_Order = @nColumn_Order, Column_Name = @Column_Name,Column_Intro = @Column_Intro حيث Column_ID = @Column_ID
إذا @@ خطأ <> 0
يبدأ
اضبط @Err = 5
اذهب إلى النهاية
End
--Print "تحديث كافة الأعمدة الفرعية ضمن هذا العمود: Column_Path، Column_Depth، Column_Order"
تحديث مجموعة Tb_Column Column_Path = Replace(Column_Path,@oColumn_Path,@nColumn_Path),Column_Depth = Column_Depth + (@nColumn_Depth-@oColumn_Depth),Column_Order = Column_Order+( @nColumn_Order-@oColumn_Order) حيث مثل Column_Path ''+ @oColumn_Path+'|%'
إذا @@ خطأ <> 0
يبدأ
اضبط @Err = 6
اذهب إلى النهاية
نهاية
نهاية
آخر
يبدأ
- احصل على المعلومات ذات الصلة بالعقدة الأم المستقبلية وقم بتعيين القيم ذات الصلة لهذه العقدة
حدد @nColumn_Depth = Column_Depth،@nColumn_Path = Column_Path من Tb_Column حيث Column_ID = @Parent_ID
إذا كان @nColumn_Depth فارغًا أو @nColumn_Path فارغًا
يبدأ
تعيين @Err = 8
اذهب إلى النهاية
نهاية
اضبط @nColumn_Depth = @nColumn_Depth +1
حدد @nColumn_Order =Max(Column_Order) من Tb_Column حيث Column_ID = @Parent_ID أو Column_Path مثل ''+@nColumn_Path+'|%'
إذا كان @nColumn_Order فارغًا
يبدأ
اضبط @Err = 9
اذهب إلى النهاية
نهاية
المجموعة @nColumn_Path = @nColumn_Path +'|'+ Ltrim(Str(@Column_ID))
IF @nColumn_Order = @oColumn_Order+1 --إذا كانت العقدة الأصلية الجديدة هي أقرب شقيق أعلى الموضع الأصلي، فسيتم ترتيب جميع العقد كن مختلفا
يبدأ
تحديث مجموعة Tb_Column Parent_ID=@Parent_ID،Column_Path = @nColumn_Path،Column_Depth = @nColumn_Depth، Column_Name = @Column_Name،Column_Intro = @Column_Intro حيث Column_ID = @Column_ID
إذا @@ خطأ <> 0
يبدأ
اضبط @Err = 10
اذهب إلى النهاية
نهاية
End
Set @nColumn_Order = @nColumn_Order + 1
- تحديث ثلاثة أجزاء 1 ترتيب السجلات التالية (أو السابقة) قبل أن تتغير هذه الشجرة 1 العقدة نفسها 3 جميع العقد الفرعية
- مقسمة إلى حركة صعودية أو حركة هبوطية
- طباعة "تحديث كافة الأعمدة بعد الموضع السابق لهذا العمود [أو الموضع بعد هذا العمود] [باستثناء الأعمدة الفرعية ضمن هذا العمود]: Column_Order"
إذا @nColumn_Order < @oColumn_Order
يبدأ
تحديث مجموعة Tb_Column Column_Order = Column_Order+@theCount حيث Column_Order<@oColumn_Order وColumn_Order >=@nColumn_Order و(Column_Path ليس مثل ''+@oColumn_Path+'|%' ) وColumn_ID<>@Column_ID
إذا @@ خطأ <> 0
يبدأ
تعيين @Err = 12
اذهب إلى النهاية
نهاية
نهاية
آخر
يبدأ
تحديث مجموعة Tb_Column Column_Order = Column_Order-@theCount حيث Column_Order >@oColumn_Order وColumn_Order<@nColumn_Order و(Column_Path ليس مثل ''+@oColumn_Path+'|%' ) وColumn_ID<>@Column_ID
إذا @@ خطأ <> 0
يبدأ
تعيين @Err = 13
اذهب إلى النهاية
نهاية
إنهاء
- طباعة "تحديث هذا العمود: Parent_ID، Column_Path، Column_Depth، Column_Order، Column_Name، Column_Intro"
طباعة "الطلب:"+Ltrim(Str(@nColumn_Order))
إذا @nColumn_Order > @oColumn_Order
قم بتعيين @nColumn_Order = @nColumn_Order - @theCount
تحديث مجموعة Tb_Column Parent_ID=@Parent_ID,Column_Path = @nColumn_Path,Column_Depth = @nColumn_Depth,Column_Order = @nColumn_Order, Column_Name = @Column_Name,Column_Intro = @Column_Intro حيث Column_ID = @Column_ID
إذا @@ خطأ <> 0
يبدأ
اضبط @Err = 10
اذهب إلى النهاية
End
--Print "تحديث كافة الأعمدة الفرعية ضمن هذا العمود: Column_Paht، Column_Depth، Column_Order"
تحديث مجموعة Tb_Column Column_Path = Replace(Column_Path,@oColumn_Path,@nColumn_Path),Column_Depth = Column_Depth + (@nColumn_Depth-@oColumn_Depth),Column_Order = Column_Order+(@nColumn_Order-@oColumn_Order) حيث Column_Path مثل ''+ @oColumn_Path+'|%'
إذا @@ خطأ <> 0
يبدأ
اضبط @Err = 11
اذهب إلى النهاية
نهاية
نهاية
النهاية:
IF @Err<>0 --إذا كان هناك خطأ، قم بإرجاع رقم الخطأ
يبدأ
التراجع تران
العودة @Err
نهاية
آخر --يرجع 0 إذا لم يكن هناك خطأ
يبدأ
ارتكاب ترانس
العودة 0
نهاية
يذهب
================================================================================================== ===================================================
الإجراء المخزن الرابع: تصنيف العرض (مجرد بيان محدد)
قائمة الفئات:
إنشاء الإجراء sp_Column_List
مثل
حدد Column_ID، Column_Name، Parent_ID، Column_Path، Column_Depth،
ترتيب_الأعمدة، مقدمة_الأعمدة
من Tb_Column
الترتيب حسب Column_Order
اذهب
=================================================================================
فيما يلي مثال للاستخدام ضمن ASP.NET، تم نشره في منتدى أحد الأصدقاء:
http://www.mzline.com/bbs/dispbbs.asp?boardID=67&ID=5044&replyID=25788&star=1&skin=0#25788