الغملاسي

كيف الحصول على أخر رقم ID من SQLDB

11 ردود في هذا الموضوع

السلام عليكم

لدي مشكلة وهي : أولاً انني لا أقوم بجلب البيانات عند حدث التحميل load event

و لنعتبر أن هنالك عدد من الصفوف في قاعدة البيانا

الان السيناريوا هو عندما أقوم بإضافة صف جديد new row وبعد تعبئته بالبيانات

أضغط على زر التحديث فيظهر الـ ID يساوي واحد وعند الضغط على الزر next يذهب إلى الصف نفسه ولكن بالرقم الحقيقي

للــ ID من قاعدة البيانات وهنا تكمن المشكلة وإن كانت بشكل مؤقت حتى يخرج المستخدم من النموذج

والسبب أنني لا أستطيع أن أضيف شيء حتى أذهب للصف الثاني , طيب مافائدة الصف الأول الوهمي ؟؟؟

وبعد البحث عن هذه المشكلة تبين لي أنني لابد أن أسترجع أخر رقم للـ ID من قاعدة البيانات بعد عملية الـ Insert .

حاولت والنتيجة كانت لا حل حتى الآن .

الطلب: كيف أستطيع أن أحصل على أخر رقم تلقائي من قاعدة البيانات SQL DataBase

HOW TO: Retrieve the Identity Value While Inserting Records

بحث في الإنترنت كثيراً وعرفت من خلال ذلك أن الـ SQL DataAdapter يقوم بهذا بشكل تلقائي

بحيث يشترط عن طريق الـ Where بأن يكون الـ ID يساوي @@IDENTITY

لكن مع ذلك المشكلة مستمرة معي , وكذلك كتبت النصوص البرمحية التالية

 Private Sub DAMain_RowUpdated(ByVal sender As Object, ByVal e As System.Data.SqlClient.SqlRowUpdatedEventArgs) Handles DAMain.RowUpdated
       Try
           If e.Status = UpdateStatus.Continue AndAlso e.StatementType = StatementType.Insert Then
               'Get NewID
               Dim cmdGetIdentity As New SqlCommand("SELECT @@IDENTITY", CnnMain)
               cmdGetIdentity.CommandType = CommandType.Text
               e.Row("SerialNumber") = Int32.Parse(cmdGetIdentity.ExecuteScalar().ToString())
               e.Row.AcceptChanges()
               MsgBox(e.Row("SerialNumber"))
           End If
       Catch ex As Exception
           MsgBox(ex.Message)
       End Try
   End Sub

لكن دون جدوى والله المستعان فكيف الحل أحسن الله إليكم ؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

لاسترجاع قيمة آخر حقل للحقل التلقائي في الجدول الموجود على SQLServer بالطبع ستكون هي أكبر قيمة ، استخدم الكود التلي:

Dim AoutNo as int36
Dim Str As String = "SELECT MAX(AoutNo) FROM tabel1 "
               Dim cmd As New OleDb.OleDbCommand(Str, OleDbConnection1)
OleDbConnection1.Open()
AoutNo = cmd.ExecuteScalar
OleDbConnection1.Close()

أتمنى أن تستفيد مما سبق

تم تعديل بواسطه seahmad
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
لاسترجاع قيمة آخر حقل للحقل التلقائي في الجدول الموجود على SQLServer بالطبع ستكون هي أكبر قيمة ، استخدم الكود التلي:

Dim AoutNo as int36
Dim Str As String = "SELECT MAX(AoutNo) FROM tabel1 "
               Dim cmd As New OleDb.OleDbCommand(Str, OleDbConnection1)
OleDbConnection1.Open()
AoutNo = cmd.ExecuteScalar
OleDbConnection1.Close()

أتمنى أن تستفيد مما سبق

لا أنصح أبداً بهذه الطريقة و بالذات للمواقع التي يكون فيها إدخال شديد. لأنه من الممكن جداً أن يتم ادخال ريكورد جديد قبل أن تقوم بعملية الإستعلام.

جرب استخدام هذه الأمر

SELECT @@IDENTITY AS 'Identity'

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

public static int add_temp_site(MainSite s)
 {
 int site_id = 0;
 SqlConnection conn = new SqlConnection(globals.conn_string);
 SqlCommand cmd = new SqlCommand();

 // init connection
 cmd.Connection = conn;

 // set procedure's name
 cmd.CommandText = "dbo.sp_add_temp_site";

 // site name
 cmd.Parameters.Add("@site_name", s.site_name);

 // site url
 cmd.Parameters.Add("@site_url", s.site_url);

 // site description
 cmd.Parameters.Add("@site_desc", s.site_desc);

 cmd.CommandType = CommandType.StoredProcedure;

 try
 {
   conn.Open();
   SqlDataReader r = cmd.ExecuteReader();
   while (r.Read())
   {
   // الرقم التسلسلي للموقع
   site_id = Convert.ToInt32(r["v_site_id"]);
   }
   r.Close();
 }
 catch
 {
 }
 finally
 {
   conn.Close();
   conn.Dispose();
   cmd.Dispose();
 }
 return site_id;
 }

الإجرائية sp_add_temp_site مكتوبة كما يلي:

insert ...............................................................

// important HERE HERE HERE
select v_site_id = SCOP_IDENTITY()

العبارة الأخير هي التي تعيد الرقم التسلسلي للسجل الذي أضفته, بمكن استخدامه بهذه الطريقة أو عن طريقة كتابة sql منفصلة ضمن برنامجك...

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أو عن طريقة كتابة sql منفصلة ضمن برنامجك...

يمكن ايضا باستعمال الدالة

 @ident_current(TableName)

حيث TableName اسم الجدول الذينريد استرجاع آخر قيمة identity منه، بشرط أن يحتوي على حقل identity .

مثال: إجراء مخزن يقوم بإضافة سجل جديد واسترجاع رقمه مباشرة:

create procedure sp_InsertNewCustomer
@CustName varchar(70), -- until the end of the parameters list
as
insert into tblCustomers values(@CustName, .................
)

select @ident_current("tblCustomers")  as CustAutoNo
go

ولتنفيذ هذا الإجراء:

SqlConnection conn = new SqlConnection(strCn);
 SqlCommand cmd = new SqlCommand();
SQL="exec sp_InsertNewCustomer "
sql+= ' put the parameters list values here

try
cn.open()
dim dtr as new SqlDataReader()
dtr=cmd.ExecuteReader(SQL)
do while dtr.Read()
    iCustNo=dtr("CustAutoNo")
loop

me.txtCustNo.text=iCustNo.ToString()
catch ex as Exception()
 msgbox ex.message
finally
 dtr.close()
 cmd.close()
 cn.close()
end try

بالتوفيق بإذن الله.

تم تعديل بواسطه walcom
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم ورحمة الله

تعليق بسيط على خطأ إملائي في كود أخونا الحبيب وليد

هو يقصد هذه الدالة IDENT_CURRENT

وليس في بدايتها علامة @

ولا أعلم أن هناك دوال في بدايتها علامة @ واحدة بل اثنتين ، وإلا ستكون متغير

أم الدالة المقصودة هنا فهي بدون علامات أصلاً IDENT_CURRENT

وطبعاً وليد أستاذنا وجل من لا يسهو :)

وأخي الكريم إسماعيل

الدالة SCOP_IDENTITY تعيد آخر IDENTITY على مستوى قاعدة البيانات كلها ، أي في أي جدول أياً كان وليس في الجدول الحالي ، فهل هذا ما قصدته ؟

والله الموفق

تم تعديل بواسطه محمد النحراوي
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

آسف على الخطأ، وهذا هو السطر الصحيح:

ident_current(TableName)

ليكون الإجراء المخزن كالتالي:

create procedure sp_InsertNewCustomer
@CustName varchar(70), -- until the end of the parameters list
as
insert into tblCustomers values(@CustName, .................
)

declare @CustAutoNo int
select @CustAutoNo= ident_current("tblCustomers")   as CustAutoNumber

go

لم يكن الكود أمامي لحظتها ، كتتبه مما استطعت تذكره، ولم أجربه.

الدالة ident_current ترجع آخر identity number في الجدول، وجعلتها في procedure وتنفذ عقب جملة الإدخال مباشرة لضمان عدم إدخال سجل آخر قبل إرجاع الidentity الخاص بالسجل الذي أدخل قبله.

ويمكن استعمال المتغير @CustAutoNo في أي جملة SQL تلي جملة إسناد القيمة إليه

-------------------------------

نقلت الموضوع لقسم SQL Server.

تم تعديل بواسطه walcom
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أخي العزيز محمد التابع SCOP_IDENTITY يعيد آخر IDENTITY تم إدراجه ضمن نفس المجال أي عند استخدام إجرائية مخزنة سيتم إعادة آخر رقم لآخر جدول تمت عملية إضافة سجل جديد أي أن هذا التابع يعمل ضمن مجال محدد أي ضمن تابع أو إجرائية أو trigger.....

أما ident_current فيعيد آخر رقم للجدول ضمن أي مجال وأي جلسة أي أنه إذا كلن هناك مستخدم آخر يقوم بعملية إضافة سجل جديد فإن هذه الدالة ستعيد نتائج غير متوقعة...

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

أخي إسماعيل أنت تقول :

أما ident_current فيعيد آخر رقم للجدول ضمن أي مجال وأي جلسة أي أنه إذا كلن هناك مستخدم آخر يقوم بعملية إضافة سجل جديد فإن هذه الدالة ستعيد نتائج غير متوقعة...

هذه أصلاً هي مزية استخدام ident_current وليست العيب الذي به

وأوضح لك

مثلاً عندنا 50 مستخدم يعملون في نفس الداتابيس ، منهم 5 حاليا يقومون بالإدخال في نفس الجدول ، فإذا كنت أنت المستخدم رقم 4 وتدخل بياناتك ثم دخل المستخدم رقم 5 وأدخل بياناته قبلك وحفظها ، فأنت هنا وباستخدام هذه الدالة (وهذه مزيتها) تحصل على آخر رقم identity مدخل وهكذا لن تتأثر عملية الإدخال لأنها لا تعتمد على المستخدم الحالي بل تعتمد على كافة العمليات على مستوى الداتابيس ، ولكن للجدول المحدد ..

والآن نوضح ما هي وظيفة الدالة SCOPE_IDENTITY ، لاحظ أنها لا تحمل أية بارمترات فلا يتم تمرير اسم جدول ولا أي شيء ، فماذا يعني هذا ؟

يعني أنك لو قمت بعمل إدخال لجدول العملاء وكان آخرidentity هو 10 ثم انتقلت لجدول الموردين لتدخل بيانات وكان عدد الموردين في الجدول هو 15 فإذا استخدمت SCOPE_IDENTITY هل تعلم ماذا سترجع لنا ؟ ستعيد لنا آخر identity على مستوى قاعدة البيانات أي ستعيد 10 وهو آخر ما تم التعامل معه في جدول العملاء وهنا طبعاً ستحدث مشكلة

أما إذا أردنا أن نرجع آخر identity على مستواك أنت فقط ومستوى الجدول الحالي (أو العملية الحالية) نستخدم الدالة @@IDENTITY

والله تعالى أعلم

تم تعديل بواسطه محمد النحراوي
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

أخواني أحسن اللهُ إليكم

بصراحة ماتوقعت هذه الردود شاكرلكم تعاونكم الّا منقطع

يا أخوان أنا رقم الأخير للـ ID تمكنت من الحصول عليه بهذا الشكل كما ذكرت سابقاً

    Private Sub DAMain_RowUpdated(ByVal sender As Object, ByVal e As System.Data.SqlClient.SqlRowUpdatedEventArgs) Handles DAMain.RowUpdated
       Try
           If e.Status = UpdateStatus.Continue AndAlso e.StatementType = StatementType.Insert Then
               'Get NewID
               Dim cmdGetIdentity As New SqlCommand("SELECT @@IDENTITY", CnnMain)
               cmdGetIdentity.CommandType = CommandType.Text
               e.Row("SerialNumber") = Int32.Parse(cmdGetIdentity.ExecuteScalar().ToString())
               e.Row.AcceptChanges()
           End If
       Catch ex As Exception
           MsgBox(ex.Message)
       End Try
   End Sub

الان مشكلتي هي عملية الـ duplicate Row عندما أقوم بالتحديث وهذا يحدث مع الـ dataView

والسبب كما ذكرت أنفاً أنه الـ dataset لا يتم تعبأتها عند تحميل النموذج إذا وجدت الحل سأخبركم (الموضوع معقد نوعاً ما )

السلام عليكم

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم أخي الكريم ،

هل وجدت الحل لمشكلتك لأني أصادف نفس المشكلة الآن وهو عند تخزين السجل الجديد يظهر سجل آخر برقم ID آخر مع العلم أن الID يعتبر Identity أي ترقيم تلقائي في قاعدة بيانات SQlServer

وجزاك الله خيرا

تم تعديل بواسطه ندى الصباح
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .