PDA

View Full Version : سوال: جلوگیری و صدور خطا در صورت حذف رکوردی که کلید آن کلید خارجی در یک جدول دیگر است



Jason.Bourne
یک شنبه 03 آذر 1392, 15:48 عصر
فرض کنید که دو جدول داریم (مانند کتاب و موضوع کتاب)

میخواهم در صورتیکه نسب به حذف یک رکورد از جدول "موضوع کتاب" اقدام شد؛ با توجه به اینکه کلید هر رکورد در این جدول یک کلید خارجی در جدول "کتاب" است پیغام خطا صادر شود.

باید چکار کنم؟
(کلمه کلید مرتبط هم به عنوان پاسخ پذیرفته می شود :چشمک::بامزه: )

pary_daryayi
یک شنبه 03 آذر 1392, 17:15 عصر
یعنی شما میخواید از حذف واقعی رکوردهای جدول موضوع کتاب جلوگیری کنید . درسته ؟
بهتره یک فیلدی برای جدول موضوع کتاب بزارید مثلا به نام status از نوع بولین.
اگر میخواید موضوعی حذف بشه , باید این فیلد رو آپدیت کنید و به 1 تغییر بدید . اینطوری id این رکورد به ظاهر حذف شده , همچنان در جدول کتاب باقی میمونه و بهم ریختگی ایجاد نمیشه.
بعد احتمالا یک قسمتی در سایتتون دارید که موضوعات کتاب نمایش داده میشه .
اونجا یک کوئری مینویسید که فقط موضوعاتی رو نمایش بده که status=0 هست ( یعنی حذف نشده )
-------------------------------

البته اگه جداولتون رو بصورت cascade تعریف کرده باشید , خودش اجازه ی حذف از جدول موضوع کتاب رو نمیده (اگه از id اون رکورد در جدول کتاب استفاده شده باشه)

Jason.Bourne
یک شنبه 03 آذر 1392, 20:10 عصر
البته اگه جداولتون رو بصورت cascade تعریف کرده باشید , خودش اجازه ی حذف از جدول موضوع کتاب رو نمیده (اگه از id اون رکورد در جدول کتاب استفاده شده باشه)

چنین چیزی مورد نظرم هست.
وقتی که ما اقدام به حذف میکنیم (توسط ()mysql_query) چه پیغام خطایی صادر میشه و چطور میشه این خطا را هندل کرد؟

H:Shojaei
یک شنبه 03 آذر 1392, 21:18 عصر
سلام
ببينيد كوئري شما براي تست اين كه كتابي با اين موضوع وجود داره يا نه به اين شكل ميشه:
$query='select * from body_books where (select * from title_book where id='value')=id';
value همون آي دي تو جدول موضوعهاست كه ميخوايد چك كنيد كه اين آي دي تو جدول كتابها هم هست يا نه...
حالا بايد كوئري رو اجرا كنيد و ببينيد سطري بهتون برميگردونه يا نه اگر برگردوند كه يعني كتاب اين موضوع وجود داره و به كاربر ميگيد نميتونه حذفش كنه اگر هم null برگردوند كه يعني كتابي با اين آي دي وجود نداره و ميتونه از جدول موضوعها هم حذف بشه.
اينام واسه اجراي كوئري:


$result=mysql_query($query);
$count=mysql_num_rows($result);
if($count>0)
{
echo 'can\'t be delete';
}
else
{
echo'deleted';
}

Jason.Bourne
یک شنبه 03 آذر 1392, 22:55 عصر
اینطوری مستلزم اجرای 2 کوئری هست (اول Select و بعد Delete)
من میخوام که از cascade استفاده کنم که نیازی به بررسی کردن من نداشته باشه.

H:Shojaei
دوشنبه 04 آذر 1392, 00:32 صبح
stackoverflow (http://stackoverflow.com/questions/12185811/mysql-on-delete-cascade-test-example)
mysql-on-delete-cascade (http://www.mysqltutorial.org/mysql-on-delete-cascade/)

as13851365
دوشنبه 04 آذر 1392, 09:17 صبح
DELETE from table1
WHERE
id=5 AND
0=(SELECT COUNT(1) from table2 WHERE id_p=5)

کد بالا رکوردهایی که در جدول یک وجود داره و زیر رکوردی در جدول دو نداره رو حذف میکنه

imanitc
دوشنبه 04 آذر 1392, 10:38 صبح
دوستان در بالا 2 راهي كه شما ميتوانيد استفاده كنيد را شرح دادن من 3 راه به صورت مختصر و مفيد شرح ميدم :


شما بايد به قول خودتون 2 تا كوئري بزنيد كه اولي چك بكنه آيا ركوردي با id مورد نظر شما در تيبل ثانويه ثبت شده اگر اين طور هست كوئري دوم رو اجرا نكنه و مانع از حذف ركورد بشه وخطا مناسب را به كاربر نمايش بده
براي استفاده از cascade شما بايد ابتدا از طريق relation و تعريف فيلد مورد نظر در 2 تيبل بصورت foreign key براي سيستم تعريف كنيد در هنگام حذف اگر ركوردي موجود بود از حذف جلوگيري كنه .براي اينكار ميتوانيد از نرم افزار هاي كمكي مانند sqlyog و يا phpmyadmin استفاده كنيد در هر 2 نرم افزار به راحتي ميتوانيد ريليشن ها تون رو تعريف كنيد البته بايد عرض كنم لازمه اين كار اين هست تيبل ها تون از موتور InnoDB استفاده بكنن و ديگه MyISAM نيست
استفاده از constraints كه دراين آدرس بيشتر مطالعه كنيد http://dev.mysql.com/doc/refman/5.0/en/constraints.html