السلام عليكم و رحمة الله و بركاته :
بعد الأسئلة الكثيرة التي وردتني عن هذا الموضوع قررت أن أضع كيفية التعامل مع هذه المشكلة كمقال بسيط ليستفيد منه كل الإخوة الذين واجهوا هذا الأمر..
المسألة ببساطة أن بعض المبرمجين أرادوا أن يعيدوا ترقيم العمود التلقائي و فوجئوا بصعوبة تحقيق ذلك. أما الحل ببساطة يكمن في إيجاد عمود بديل لعمود الترقيم التلقائي ليأخذ مكانه .. طبعا تنفيذ ذلك يتطلب مراعاة أمور كثيرة سأسردها بالترتيب حتى يتمكن من تطبيقها حتى المبرمجين غير الملمين بقواعد البيانات SQL Server..
و هذا مثال من الألف إلى الياء:
use tempdb
go
-- إنشاء جدول للمثال
Create Table TestTB(Id int identity, Name varchar(50) )
Go
-- ادخال بيانات
Insert into TestTB(Name) Select 'Ahmad'
Insert into TestTB(Name) Select 'Smeer'
Insert into TestTB(Name) Select 'Ibraheem'
Insert into TestTB(Name) Select 'Salem'
Insert into TestTB(Name) Select 'Hala'
Insert into TestTB(Name) Select 'Nehad'
go
-- خلق فجوة في الترقيم عن طريق حذف سجلات في الوسط
Delete From TestTB Where Name in ('Smeer' , 'Ibraheem')
go
-- مشاهدة البيانات بعد خلق الفجوة للمعاينة
Select * From TestTB
Go
-- حل المشكلة
-- إضافة عمود جديد للجدول بدون ترقيم تلقائي
Alter Table TestTB Add IDNew int
Go
-- نقل القيم من عمود الترقيم التلقائي إلى العمود الجديد
Update TestTB Set IDNew = Id
Go-- معاينة الجدول بعد إضافة العمودSelect * From TestTBGo
خطوات هامة:
1- احذف كل العلاقات ما بين العمود القديم و باقي الجداول على أن تدونها على ورقة لكي تعيد انشائها لكن مع العمود الجديد
2- اجعل العمود الجديد مفتاح رئيسي بدلا من العمود القديم
3- أعد إنشاء المفاتيح الثانوية لكي تتعامل مع العمود الجديد مع تفعيل الخيار On Update Cascade
4- بعد التأكد من أن العلاقات قد تم انشاؤها بشكل صحيح يمكن اعادة ترقيم العمود الجديد بالكامل ..
ملاحظة مهمة
يجب أن يكون الخيار On Update Cascade موجود في كل العلاقات التي أعدت إنشاءها
بحيث عندما تعيد ترقيم العمود الجديد (الذي أصبح مفتاح رئيسي) فإنها
تنعكس على المفتاح الثانوي في الجدول المرتبط بهذا العمود
-- إعادة الترقيم باستخدام المؤشر الديناميكي Declare @C Cursor Set @C = Cursor dynamic for Select IdNew from TestTB for update Declare @NewId int = 1 open @C Fetch Next From @C While (@@FETCH_STATUS = 0) begin Update TestTB Set IdNew = @NewId Where Current of @C Set @NewId = @NewId + 1 Fetch Next From @C end Go -- حذف العمود القديم Alter Table TestTB Drop Column Id Go -- تغيير اسم العمود الجديد ليصبح مطابق لاسم القديم exec sp_rename 'TestTB.IdNew' , 'Id' Go -- معاينة بعد التعديلات Select * From TestTB Go -- بدلاً من الترقيم التلقائي أنصح بالقيام بذلك بشكل يدوي لأنه يعطيك ديناميكية أكبر للتعامل مع هذا العمود -- و هذا مثال على إجراء اضافة سجل و اعطاء العمود الرقم التالي المناسب Create proc TestTB_Insert @Id int = null out, @Name Varchar(50) = null AS Select @Id= IsNull(max(Id), 0) + 1 from TestTB Insert TestTB(Id, Name) Select @Id, @Name GO
أرجو الفائدة للجميع