PDA

View Full Version : سوال: ارسال اطلاعات به جدول پدر و فرزند



maktab
دوشنبه 19 تیر 1391, 11:48 صبح
سلام
من سه تا جدول دارم. یکی بعنوان پدر و دو جدول دیگه فرزند (از جدول پدر ارث میبرند).
مثلا پرسنل میشه جدول اصلی. معلم و کارمندان مدرسه میشه جدول های فرزند.
خب حالا برای جدول پرسنل یک id قرار دادم و همان id را هم برای دو جدول دیگه تعریف کردم. و به هم لینک دادم. این id در جدول پرسنل بصورت Identity هستش و خودکار تولید میشه. اما در جدول های دیگه به این صورت نیست و باید id متناظر با جدول پرسنل ثبت بشه. برای عملیات به این شکل عمل میکنم:
وقتی بخوام یک معلم ثبت کنم ابتدا اطلاعات اصلی (اطلاعات مشترک) را در جدول پرسنل قرار میدم و sql یک id برای من درست میکند حال باید آن id را بدست بیارم و با بقیه اطلاعات در جدول معلم قرار بدم.
آیا این نوع درج کردن درسته؟ اگر صحیح است به چه شکل میشه id را بدست آورد؟
برای ارتباط با sql هم از EF استفاده میکنم.

veniz2008
دوشنبه 19 تیر 1391, 12:30 عصر
سلام، برای ارتباط بین جداول شما ناچارید که از کلید اصلی و کلید خارجی استفاده کنید(همین کاری که الان انجام دادید)،البته ممکنه راه دیگه ای هم باشه ولی این بهترین و اصولی ترین راه هستش. برای بدست آوردن id هم خیلی راحت میتونید این کار رو انجام بدید، من دو حالت رو برای این کار در نظر میگیرم:
حالت اول : شما چند تا رکورد در جدول پرسنل ثبت کردید، حالا میخواید لیست تمام id ها رو داشته باشید که با یه دستور select و ریختن اون داخل یه دیتاتیبل میتونید به همه id ها دسترسی داشته باشید. به اینصورت:

select id from personel
2. شما چند تا رکورد ثبت کردید و میخواید id مربوط به آخرین رکوردی که در جدول پرسنل ثبت کردید رو بدست بیارید، اینم با یه دستور select بصورت زیر براحتی قابل انجام هست:

select top(1) id from personel order by id desc
موفق باشید.

maktab
دوشنبه 19 تیر 1391, 12:59 عصر
متاسفانه هیچ کدام از این روش ها مناسب کار من نیستند.
عملکرد سیستم به این شکله:
دو کاربر در حال ارسال اطلاعات هستند. هر دو هم در حال درج اطلاعات معلم هستند. وقتی اطلاعات ثبت میشند به این شکل ممکنه ثبت بشه اطلاعات کاربر اول در جدول پرسنل ثبت بشه و اطلاعات کاربر دوم نیز در جدول پرسنل ثبت بشه. حالا اطلاعات کاربر اول در جدول معلم باید ثبت بشه و اطلاعات کاربر دوم نیز در جدول معلم ثبت بشه. در این حالت از کجا میشه متوجه شد id اطلاعات کاربر اول و کاربر دوم چیه؟
من این حالت رو گفتم چون ممکنه نشه همیشه به آخرین اطلاعات ارسالی حساب باز کرد. یا اینکه من اشتباه میکنم؟ (در برنامه های چند کاربره)

cherchil_hra
دوشنبه 19 تیر 1391, 13:08 عصر
از تابع SCOPE_IDENTITY بعداز دستور insert استفاده کن!

veniz2008
دوشنبه 19 تیر 1391, 13:08 عصر
واسه این کار شما باید یه نشونه ای از کاربری که با سیستم کار میکنه و اطلاعات رو ثبت میکنه در جدول پرسنل ذخیره کنید. مثلا کاربر1 با شماره شناسایی منحصر به فرد ali1000 میاد و اطلاعات مورد نظرش رو وارد میکنه حالا موقعی که میخواد ثبت کنه باید شماره شناسایی این کاربر رو به همراه اطلاعاتی که تایپ کرده درون جدول ذخیره کنید تا بفهمید این اطلاعات توسط کدوم کاربر ثبت شده. دقیقا همینطور برای کاربر دوم هم یک شماره شناسایی منحصر به فرد(منظورم کلید هستش) باید داشته باشید.

maktab
دوشنبه 19 تیر 1391, 13:33 عصر
از تابع SCOPE_IDENTITY بعداز دستور insert استفاده کن!

اگر ممکنه یه مثال با کد بزنید. به چه شکل میتوان از این تابع استفاده کرد؟ آیا این روش مناسب تر است یا روشی که دوستمان گفت؟

cherchil_hra
دوشنبه 19 تیر 1391, 14:58 عصر
اگر ممکنه یه مثال با کد بزنید. به چه شکل میتوان از این تابع استفاده کرد؟ آیا این روش مناسب تر است یا روشی که دوستمان گفت؟

try catch (با فرض این که شما از sql 2005 و یا بالاتر استفاده می کنید)
SCOPE_IDENTITY آخرین مقدار فیلد IDENTITY که توسط جدولتان (پرسنل) در اینجا درج کردید را بر می گرداند. بنابراین اگر دو نفر همزمان هم درج کنند، شما ID صحیح را خواهی داشت.

به فرض اینکه insert جدول پرسنل انجام شود ولی بنابر دلایلی برای جدول معلم این کار انجام نشود. پس بهتر هست که insert قبلی هم اِعمال نشود. در نتیجه چون دو دستور insert (یا بیشتر) دارید بهتر هست که از TRANSACTION استفاده کنید.
به ازای هر TRANSACTION یک واحد به @@TRANCOUNT شما اضافه می شود و هر کدام که به commit برسد یک واحد کم.
بنابراین اگر مقدار آن بیشتر از 0 باشد و خطایی رخ داده باشد دستور rollback اجرا می شود و دستورات تمام TRANSACTION هایی که به commit نرسیده باشند بی اثر می شود.(مثل اینکه هیچ چیزی درج نشده)

چون دستورات شما باید همگی باهم اجرا شوند می توانی از این شرط هم استفاده نکنی و با ایجاد هر خطایی در قسمت catch از rollback استفاده کنی.
DECLARE @id AS INT
BEGIN TRY
BEGIN TRANSACTION
--INSERT ثبت نام
set @id = SCOPE_IDENTITY()
--INSERT معلم يا کارمند
--@ID با استفاده از
COMMIT
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK

END CATCH