تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
اعادة الترقيم لحقل الاي دي
#1
السلام عليكم ورحمة الله وبركاته
الكثير من الاخوة تزعجهم الفجوات الرقمية التسلسلية للاي دي عند حذف السجلات من الجدول
وبالرغم من ان الامر طبيعي وحقيقي لان الاي دي هو معرف فريد لكل سجل ولايجوز تكراره او تغييره لانه هو الدليل الذي تتم به عمليات الحذف والتعديل
والاهم هو ان المعرف هو حقل الربط العلائقي بين جدول (أب) وجدول (ابن) اي مفتاح رئيسي ومفتاح فرعي وبمجرد التفكير في اعادة التسلسل
للاي دي هو بحد ذاته خطأ برمجي قاتل ويترتب على اعادة الترقيم كارثة في البيانات وسيختلط الحابل بالنابل
كما ان الاي دي ان كان ترقيم تلقائي فإننا لايمكن اعادة الترقيم للجدول لاننا سنضطر الى حذف المفتاح ومن ثم حقل الاي دي وبعدها اعادة انشائه وحذف كل البيانات واعادة الادخال (حفلة طويلة)
اذا ماهي الحالة الممكن اعادة ترقيم الاي دي فيها ؟
اذا كان الجدول ليس له اي ارتباط مع جداول اخرى وحقل الاي دي لايؤثر على التعامل مع السجل ورقم الاي دي غير مهم بالنسبة للسجل 
وايضا يجب ان لايكون ترقيم تلقائي (AutoNumber) اي اننا ندخل الاي دي عبر دالة Max في هذه الحالة فقط يمكننا اعادة تسلسله (بالرغم من اني لاأحبذ ذلك)
وقد بحثت كثيرا في المنتدى والانترنت عن كود يؤدي المطلوب لكن دون جدوى وكل الاجابات عن الاسئلة المتعلقة بالموضوع هي رفض اعادة الترقيم او الاحجام عن الاجابة وانا من انصار هذا الرأي
لكن الحاح السائلين جعلني ابحث عن الطريقة والكود من باب العلم بالشيئ ويكون لمنتدنا الغالي السبق في الاجابة
الصراحة لم استفد من اي معلومة من قرأتها وهذا الكود أخذ مني وقتا ليس باليسير واتعبني حتى تم المطلوب
المعضلة كانت كيف سيتم تعدبل التسلسل القديم بالجديد وبخاصة اننا سنستخدم الرقم القديم ليكون شرط التعدبل !!!!!
لن اطيل عليكم انشأت مثال لجدول وحيد يمكن الحفط والتعديل والحذف فيه لنترك الفجوات وبعدها نضغط عل زر اعادة ترتيب الاي دي
وهذا هو الكود 
كود :
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

       Try
           Dim Cmd1, Cmd2 As New OleDbCommand()
           Dim da As New OleDbDataAdapter()
           Dim Dt1, dt2 As New DataTable()
           Dim Lstb As New ListBox()
           Dt1.Clear()
           ' جلب كل البيانات
           da = New OleDbDataAdapter("select * from Personal ", Con)
           da.Fill(Dt1)

           Lstb.Items.Clear()
           ' اضافة الاي دي الى الليست بوكس لاستخدامها
           For x As Integer = 0 To Dt1.Rows.Count - 1
               Lstb.Items.Add(Dt1.Rows(x)(0))
           Next


           For i As Integer = 0 To Lstb.Items.Count - 1
               dt2.Clear()
               ' جلب بيانات صف واحد بدلالة الاي دي المخزن في الليست بوكس
               da = New OleDbDataAdapter("select * from Personal where Cv_id = " & CInt(Lstb.Items(i)) & "", Con)
               da.Fill(dt2)
               'تخزين السجل في مصفوفة
               Dim MyString() As String = {dt2.Rows(0)(0).ToString(), dt2.Rows(0)(1).ToString(), dt2.Rows(0)(2).ToString(), dt2.Rows(0)(3).ToString(), dt2.Rows(0)(4).ToString(), dt2.Rows(0)(5).ToString(), dt2.Rows(0)(6).ToString()}

               Try
                   'حذف السجل الذي خزن في المصفوفة

                   Cmd2 = New OleDbCommand("Delete From Personal Where CV_ID=@CV_ID", Con)
                   Cmd2.Parameters.Add(New OleDbParameter("@CV_ID", OleDbType.Integer)).Value = CInt(Lstb.Items(i))
                   If Con.State = ConnectionState.Open Then Con.Close()
                   Con.Open()
                   Cmd2.ExecuteNonQuery()
                   Con.Close()

               Catch ex As Exception
               Finally
                   Con.Close()
               End Try

               ' اضافةالسجل مع الترقيم الجديد الى الجدول

               Cmd1 = New OleDbCommand("insert into Personal(CV_ID,CV_Name,CV_BirthDay,CV_Job,CV_Salary,CV_Programer,CV_Adress) Values(@CV_ID,@CV_Name,@CV_BirthDay,@CV_Job,@CV_Salary,@CV_Programer,@CV_Adress)", Con)
               Cmd1.Parameters.Add(New OleDbParameter("@CV_ID", OleDbType.Integer)).Value = i + 1
               Cmd1.Parameters.Add(New OleDbParameter("@CV_Name", OleDbType.VarWChar)).Value = MyString(1)
               Cmd1.Parameters.Add(New OleDbParameter("@CV_BirthDay", OleDbType.Date)).Value = MyString(2)
               Cmd1.Parameters.Add(New OleDbParameter("@CV_Job", OleDbType.VarWChar)).Value = MyString(3)
               Cmd1.Parameters.Add(New OleDbParameter("@CV_Salary", OleDbType.VarWChar)).Value = Convert.ToUInt32(MyString(4))
               Cmd1.Parameters.Add(New OleDbParameter("@CV_Programer", OleDbType.Boolean)).Value = MyString(5)
               Cmd1.Parameters.Add(New OleDbParameter("@CV_Adress", OleDbType.VarWChar)).Value = MyString(6)

               If Con.State = ConnectionState.Open Then Con.Close()
               Con.Open()
               Cmd1.ExecuteNonQuery()
               Con.Close()


           Next

       Catch ex As Exception

       End Try
       SelectAll_Personal()
       MessageBox.Show("تمت عملية اعادة الترقيم  بنجاح", "تعديل", MessageBoxButtons.OK, MessageBoxIcon.Information)
   End Sub


الملفات المرفقة
.zip   Kebboud_Renumbring_Id.zip (الحجم : 126.23 ك ب / التحميلات : 21)
اعمل الخير واجرك لاتنتظره فالله خير من اليك يرده
البرمجة ليست مجرد كود بل هي منهج تفكير منطقي لحل المشكلات







الرد
تم الشكر بواسطة: asemshahen5 , kebboud , tryold
#2
طريقة جميلة لاكن الافضل حذف عامود الترقيم التلقائي و إنشاء عامود جديد .

PHP كود :
Private Sub Button13_Click(sender As ObjectAs EventArgsHandles Button13.Click
    If DT_CANDIDATE
.Rows.Count 0 Then
        MsgBox
("الجدول فارغ من السجلات يتطلب وجود سجل واحد على الاقل"16 524288"تنبيه")
 
       Exit Sub
    End 
If
 
   If MsgBox("  هل تريد استعادة ترقيم السجلات  " " ؟ "MsgBoxStyle.Exclamation MsgBoxStyle.MsgBoxRight MsgBoxStyle.OkCancel"استعادة ترقيم السجلات") = MsgBoxResult.Cancel Then Exit Sub
    Try
        Application
.DoEvents()
 
       Dim cmd As New OleDb.OleDbCommand(""Conne_2019)
 
       Conne_2019.Open()
 
       ''ID كود حذف المفتاح من حقل الترقيم التلقائي الي اسمه  
        cmd
.CommandText "ALTER TABLE TBL_CANDIDATE DROP CONSTRAINT PrimaryKey"
 
       cmd.ExecuteNonQuery()
 
       ''ID كود حذف حقل الترقيم التلقائي الي اسمه  
        cmd
.CommandText "ALTER TABLE TBL_CANDIDATE DROP COLUMN CANDIDATE_Id"
 
       cmd.ExecuteNonQuery()
 
       ''مع وضع مفتاح له ID كود انشاء حقل الترقيم التلقائي الي اسمه  
        cmd
.CommandText "ALTER TABLE TBL_CANDIDATE ADD COLUMN CANDIDATE_Id COUNTER CONSTRAINT [PrimaryKey] Primary key"
 
       cmd.ExecuteNonQuery()
 
       ''تحديث قاعدة البيانات
        DT_CANDIDATE
.Clear()
 
       Conne_2019.Close()
 
       Dim Da As New OleDbDataAdapter("SELECT * From TBL_CANDIDATE"Conne_2019''
 
       If Conne_2019.State 1 Then Conne_2019.Close()
 
       Conne_2019.Open()
 
       Da.Fill(DT_CANDIDATE)
 
       MsgBox("تم بنجاح استعادة تسلسل السجلات"64 524288"نجاح")
 
   Catch ex As Exception
        MessageBox
.Show(ex.Message"Error"MessageBoxButtons.OKMessageBoxIcon.Error)
 
   End Try
End Sub 
الرد
تم الشكر بواسطة: programmer_25 , tryold , ابراهيم ايبو
#3
(03-08-21, 02:43 AM)ابراهيم ايبو كتب : السلام عليكم ورحمة الله وبركاته
الكثير من الاخوة تزعجهم الفجوات الرقمية التسلسلية للاي دي عند حذف السجلات من الجدول
وبالرغم من ان الامر طبيعي وحقيقي لان الاي دي هو معرف فريد لكل سجل ولايجوز تكراره او تغييره لانه هو الدليل الذي تتم به عمليات الحذف والتعديل
والاهم هو ان المعرف هو حقل الربط العلائقي بين جدول (أب) وجدول (ابن) اي مفتاح رئيسي ومفتاح فرعي وبمجرد التفكير في اعادة التسلسل
للاي دي هو بحد ذاته خطأ برمجي قاتل ويترتب على اعادة الترقيم كارثة في البيانات وسيختلط الحابل بالنابل
كما ان الاي دي ان كان ترقيم تلقائي فإننا لايمكن اعادة الترقيم للجدول لاننا سنضطر الى حذف المفتاح ومن ثم حقل الاي دي وبعدها اعادة انشائه وحذف كل البيانات واعادة الادخال (حفلة طويلة)
اذا ماهي الحالة الممكن اعادة ترقيم الاي دي فيها ؟
اذا كان الجدول ليس له اي ارتباط مع جداول اخرى وحقل الاي دي لايؤثر على التعامل مع السجل ورقم الاي دي غير مهم بالنسبة للسجل 
وايضا يجب ان لايكون ترقيم تلقائي (AutoNumber) اي اننا ندخل الاي دي عبر دالة Max في هذه الحالة فقط يمكننا اعادة تسلسله (بالرغم من اني لاأحبذ ذلك)
وقد بحثت كثيرا في المنتدى والانترنت عن كود يؤدي المطلوب لكن دون جدوى وكل الاجابات عن الاسئلة المتعلقة بالموضوع هي رفض اعادة الترقيم او الاحجام عن الاجابة وانا من انصار هذا الرأي
لكن الحاح السائلين جعلني ابحث عن الطريقة والكود من باب العلم بالشيئ ويكون لمنتدنا الغالي السبق في الاجابة
الصراحة لم استفد من اي معلومة من قرأتها وهذا الكود أخذ مني وقتا ليس باليسير واتعبني حتى تم المطلوب
المعضلة كانت كيف سيتم تعدبل التسلسل القديم بالجديد وبخاصة اننا سنستخدم الرقم القديم ليكون شرط التعدبل !!!!!
لن اطيل عليكم انشأت مثال لجدول وحيد يمكن الحفط والتعديل والحذف فيه لنترك الفجوات وبعدها نضغط عل زر اعادة ترتيب الاي دي
وهذا هو الكود 
كود :
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

       Try
           Dim Cmd1, Cmd2 As New OleDbCommand()
           Dim da As New OleDbDataAdapter()
           Dim Dt1, dt2 As New DataTable()
           Dim Lstb As New ListBox()
           Dt1.Clear()
           ' جلب كل البيانات
           da = New OleDbDataAdapter("select * from Personal ", Con)
           da.Fill(Dt1)

           Lstb.Items.Clear()
           ' اضافة الاي دي الى الليست بوكس لاستخدامها
           For x As Integer = 0 To Dt1.Rows.Count - 1
               Lstb.Items.Add(Dt1.Rows(x)(0))
           Next


           For i As Integer = 0 To Lstb.Items.Count - 1
               dt2.Clear()
               ' جلب بيانات صف واحد بدلالة الاي دي المخزن في الليست بوكس
               da = New OleDbDataAdapter("select * from Personal where Cv_id = " & CInt(Lstb.Items(i)) & "", Con)
               da.Fill(dt2)
               'تخزين السجل في مصفوفة
               Dim MyString() As String = {dt2.Rows(0)(0).ToString(), dt2.Rows(0)(1).ToString(), dt2.Rows(0)(2).ToString(), dt2.Rows(0)(3).ToString(), dt2.Rows(0)(4).ToString(), dt2.Rows(0)(5).ToString(), dt2.Rows(0)(6).ToString()}

               Try
                   'حذف السجل الذي خزن في المصفوفة

                   Cmd2 = New OleDbCommand("Delete From Personal Where CV_ID=@CV_ID", Con)
                   Cmd2.Parameters.Add(New OleDbParameter("@CV_ID", OleDbType.Integer)).Value = CInt(Lstb.Items(i))
                   If Con.State = ConnectionState.Open Then Con.Close()
                   Con.Open()
                   Cmd2.ExecuteNonQuery()
                   Con.Close()

               Catch ex As Exception
               Finally
                   Con.Close()
               End Try

               ' اضافةالسجل مع الترقيم الجديد الى الجدول

               Cmd1 = New OleDbCommand("insert into Personal(CV_ID,CV_Name,CV_BirthDay,CV_Job,CV_Salary,CV_Programer,CV_Adress) Values(@CV_ID,@CV_Name,@CV_BirthDay,@CV_Job,@CV_Salary,@CV_Programer,@CV_Adress)", Con)
               Cmd1.Parameters.Add(New OleDbParameter("@CV_ID", OleDbType.Integer)).Value = i + 1
               Cmd1.Parameters.Add(New OleDbParameter("@CV_Name", OleDbType.VarWChar)).Value = MyString(1)
               Cmd1.Parameters.Add(New OleDbParameter("@CV_BirthDay", OleDbType.Date)).Value = MyString(2)
               Cmd1.Parameters.Add(New OleDbParameter("@CV_Job", OleDbType.VarWChar)).Value = MyString(3)
               Cmd1.Parameters.Add(New OleDbParameter("@CV_Salary", OleDbType.VarWChar)).Value = Convert.ToUInt32(MyString(4))
               Cmd1.Parameters.Add(New OleDbParameter("@CV_Programer", OleDbType.Boolean)).Value = MyString(5)
               Cmd1.Parameters.Add(New OleDbParameter("@CV_Adress", OleDbType.VarWChar)).Value = MyString(6)

               If Con.State = ConnectionState.Open Then Con.Close()
               Con.Open()
               Cmd1.ExecuteNonQuery()
               Con.Close()


           Next

       Catch ex As Exception

       End Try
       SelectAll_Personal()
       MessageBox.Show("تمت عملية اعادة الترقيم  بنجاح", "تعديل", MessageBoxButtons.OK, MessageBoxIcon.Information)
   End Sub


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


    Heart ربي زدني علما  Heart

الرد
تم الشكر بواسطة: ابراهيم ايبو , asemshahen5
#4
السلام عليكم ورحمة الله وبركاته
شكرا لك اخي عاصم على اهتمامك ومشاركتك الثمينة
بالنسبة لكودك اعرفه لكن لم يعمل معي سابقا 
وقمت بتجربة كودك ايضا نفس المشكلة يحذف المفتاح ولايكمل 
ومن اجل ذلك قمت بالعمل حسب مفهومي بانشاء هذا الكود فقط المشكلة فيه هو اذا كان عدد السجلات كبيرا فسوف يستغرق بعض الوقت في التنفيذ ولايعمل اذا كان الحقل ترقيم تلقائي فكما تعلم لايمكن اعادة الترقيم الا اذا حذفنا المفتاح والحقل واعادة الانشاء
حتى اقطع الشك باليقين اتمنى ان تجرب كودك وتخبرني بالنتيجة 
شكرا لك ياغالي
الاخ الكريم Kebboud 
شكرا لك على هذا الاطراء اخجلتني
 دمت بخير ياغالي
اعمل الخير واجرك لاتنتظره فالله خير من اليك يرده
البرمجة ليست مجرد كود بل هي منهج تفكير منطقي لحل المشكلات







الرد
تم الشكر بواسطة: asemshahen5
#5
هذا مثال على الكود :


الملفات المرفقة
.zip   TestRetypeID.zip (الحجم : 542.47 ك ب / التحميلات : 8)
الرد
تم الشكر بواسطة: ابراهيم ايبو
#6
بارك الله فيك ولك اخي عاصم
عمل الكود اول مرة ثم اضفت وحذفت ولم يعمل في المرة الثانية بعدها اضفت وحذفت وعمل الكود بشكل جيد
دمت بخير ياغالي
اعمل الخير واجرك لاتنتظره فالله خير من اليك يرده
البرمجة ليست مجرد كود بل هي منهج تفكير منطقي لحل المشكلات







الرد
تم الشكر بواسطة: asemshahen5 , asmarsou



التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم