ورود

View Full Version : تقاضای کمک برای عدم delete و یا update بصورت آبشاری(cascade)



sajad_3dmax
دوشنبه 03 آذر 1393, 11:12 صبح
با سلام خدمت تمامی دوستان عزیز
بنده نرم افزاری طراحی کردم که کد نویسیش رو با C#‎‎‎‎‎‎ انجام دادم. بانک اطلاعاتیش دو تا مشکل داره.
1- تو ارتباطات جداول نمیخوام حذف بصورت cascade باشه چون بنظرم غیر منطقیه. لزومی نداره که اگه مثلا کاربری حذف شد تمام سوابق کاریش حذف بشه. منتها اگه تو خواص ارتباطات بیام delete رو برابر no action قرار بدم موقع حذف کردن اطلاعات جدولی که کلید اصلی داره اگه این کلید تو جدول دیگه ای بکار برده شده باشه(بعنوان کلید خارجی )exeption رخ میده که conflict رخ داده که البته اگه بجای no action گزینه cascade رو انتخاب کنم مشکل conflict حل میشه. اما من میخوام تنظیم روی no action باشه و نه cascade. به همون دلیلی که توضیح دادم.که حتی خود همین update باعث معضل دیگه ای تو ارتباطات بانک میشه به نام cycle که مشکل دوم منه. چطور باید این گزینه no action رو بکار ببرم.
2- دوم اینکه بعضی ارتباطات باعث ایجاد cycle میشوند. چرا؟
مثلا من جدول کاربران رو دارم به اسم users. تو باقی جداولم (tbl_1,tbl_2,...) هم یه فیلدی گذاشتم بعنوان کاربر ثبت کننده که هر اطلاعاتی که ثبت بشه نام کاربر هم ثبت بشه.اگه تنظیم delete بصورت cascade باشه در تمام ارتباطات cycleرخ میده. چرا؟ مشکل از کجاست؟

مهدی نان شکری
چهارشنبه 05 آذر 1393, 14:49 عصر
با سلام
Foreign key constraint به منظور محدود کردن دامنه مقادیر فیلد های یک جدول ایجاد می شود.
مقادیر معتبر فیلد مورد نظر از جدولی (جدول اصلی) که دارای رابطه با جدول مورد بحث می باشد به دست می آید.
اگر چنان که از جدول اصلی رکوردی حذف شود که در ارتباط با جدول وابسته بوده باشد، کلیه رکورد های مرتبط با رکورد حذف شده در جدول وابسته یتیم خواهند شد که به این وضع شکسته شدن relational integrity گفته می شود.
وظیفه اصلی Foreign key constraint جلوگیری از شکسته شدن relational integrity می باشد.

مهدی نان شکری
چهارشنبه 05 آذر 1393, 15:19 عصر
فرض کنید در یک پایگاه داده 3 جدول Table_A، Table_B و Table_C وجود دارد به طوری که فیلدی از جدول B با جدول A Foreign key constraint داشته و همچنین فیلدی از جدول C با فیلدی از جدول B دارای Foreign key constraint می باشد.
حال با فرض این که هر دو قید مطرح شده دارای خاصیت ON DELETE CASCADE باشد، با حذف رکوردی از جدول A کلیه رکورد های وابسته در جدول B نیز حذف خواهند شد و با حذف شدن رکورد های جدول B کلیه رکورد های وابسته به آن در جدول C نیز حذف خواهند شد.
اولین قاعده موجود در MS SQL Server (در اوراکل این قاعده وجود ندارد) این است که کلیه Cascade هایی که از انجام یک عمل Delete یا Update روی می دهد می بایست یک درخت را شکل دهند. درخت گرافی است که هیچ گونه دوری در آن وجود ندارد.
به بیان ساده تر در یک عمل Delete و یا Update اگر کلیه جداول متاثر را لیست نمایید نباید هیچ کدام از جداول بیش از یک بار در لیست شما دیده شود.
برای این منظور در جداولی که شامل دور می باشند خاصیت NO ACTION را انتخاب نمایید و برای حذف و آپدیت می توانید از trigger کمک بگیرید.

sajad_3dmax
پنج شنبه 06 آذر 1393, 23:46 عصر
احسنت بر شما استاد. واقعا حذ بردم.
میشه بفرمایید برای کسب این چنین اطلاعاتی به چه مراجعی رجوع کنم.
درواقع منظورم اینه که استاد اینا رو از کجا یاد گرفتین با سلامتی. به ما هم بفرمایین بریم دنبالش

sajad_3dmax
پنج شنبه 06 آذر 1393, 23:51 عصر
با سلام
وظیفه اصلی Foreign key constraint جلوگیری از شکسته شدن relational integrity می باشد.

با تشکر استاد گرامی.
خوب اما این مطلب رو هم قبول میفرمیید که با حذف اطلاعات کلید اصلی کلید خرجی باید باقی بمونه. چون نباید سوابق از بین بروند. راه حل چیست.مثلا بنده یک جدول کالا دارم. و جدول دیگری با عنوان جدول فروش.
حالا پس از یه مدتی دیگه یه کالای خاصی رو ندارم و میخوام برای همیشه از تو لیستم بردارم. اما نمیخوام سوابق فروش اون کالام رو از دست بدم. راه حل چیه؟
و سوال بعدیم اینه که پس کاربرد no action چیه؟

حمیدرضاصادقیان
جمعه 07 آذر 1393, 03:07 صبح
سلام.
وقتی که میخواهید رکوردی که اصلی هست رو حذف کنید ولی زیر مجموعه هاش حذف نشه باید روی default value بذارید یا روی null. در اینصورت رکورد اصلی رو حذف میکنه و مقدار کلید در جداول وابسته رو برابر null قرار میده.
کار no action یعنی هیچ کاری انجام نده.یعنی من خودم همه موارد رو کنترل میکنم و SQL Server ، تو نیازی نیست کاری برای من انجام بدی.

مهدی نان شکری
شنبه 08 آذر 1393, 11:03 صبح
با سلام
مطلب آقای صادقیان کاملا درست می باشد ولی سابقه قابل رد یابی نیست. مثلا اگر کالای A از جدول Product حذف شود در جدول Orders مقدار فیلد ProductID برابر Null می گردد. و بعد ها فقط مقدار فروش قابل گزارش گیری خواهد بود نه به تفکیک کالا.
به همین دلیل شاید روش های دیگه رو انتخاب کنید بهتر باشه.
موفق باشید.

حمیدرضاصادقیان
شنبه 08 آذر 1393, 17:23 عصر
منم روشی بهشون پیشنهاد ندادم فقط گفتم به این شکل داره SQL Server رفتار میکنه.
بله این روش اصلا قابل ردیابی نیست و میشه مثلا ازجدولی به عنوان Deleted استفاده کرد یا به صورت مجازی رکورد رو حذف کرد یا تکنیکهای دیگه ای رو استفاده کرد.