ورود

View Full Version : مشکل با Insert و کلید خارجی



lvlina_r
پنج شنبه 25 شهریور 1389, 14:33 عصر
سلام
من جداولی به فرم زیر دارم
http://www.irfreeup.com/images/otonjiu2o5n5h5dr20fy.jpg (http://www.irfreeup.com/)
می خواهم با دستورات زیر رکوردهایی را از دیتابیس دیگرم وارد جدول Order کنم


INSERT INTO f.dbo.Tbl_Order
(orderID, VariableValue,idx)
select
s.SadFid ,
drv.DrvActivity,
fi.idx
from
saledraft s CROSS JOIN driver drv
inner join
f.dbo.Tbl_Input fi ON fi.xname LIKE N'%فعالیت %'

اما ارور زیر را می دهد


The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Tbl_Order_Tbl_Priority". The conflict occurred in database "f", table "dbo.Tbl_Priority", column 'OrderId'.

علت چیست؟؟

behrouzlo
پنج شنبه 25 شهریور 1389, 15:20 عصر
با توجه به رابطه ای که بین جدول Tbl_Priority و Tbl_Order وجود دارد شما باید اول سفارشها را به Tbl_Priority اضافه کنید و بعد به Tbl_Order تا محدودیت کلید خارجی که بر روی آن تعریف شده است ب آورده شود.(در واقع OrderId باید در جدول Tbl_Priority موجود باشد و سپس به Tbl_Order اضافه شود)

بهزادصادقی
پنج شنبه 25 شهریور 1389, 15:27 عصر
اولا از شما تشکر می کنم که اطلاعات مربوط به سوال خود را به این جامع ای و با این دقت در متن پست خود فراهم آورده اید. اگر همه سوالات مطرح شده در این تالار با این حوصله طرح شوند، درصد خیلی بیشتری از مسائل مطرح شده حل خواهند شد.

نگاه کنید، نفس یک رابطه «کلید خارجی» بین دو تا جدول این است که با برقراری همچین ارتباطی ما از SQL Server می خواهیم تا یک محدودیت خیلی خاصی را روی یکی از این جداول اجرا کند، و نگذارد هیچ سطری به آن جدول اضافه شود، مگر اینکه آن سطر دارای یک شرایط خاصی یاشد. اصلا از دو اصطلاح خاص برای اشاره کردن به مفهوم foreign key یا کلید خارجی استفاده می شود. یکی «رابطه کلید خارحی» یا foreign key relationship می باشد، و دیگری «محدودیت کلید خارجی» یا foreign key constraint می باشد. پس اعمال یک نوع محدودیت در نفس مفهوم کلید خارجی نهفته است.

مشکلی که الان شما به آن برخورد کرده اید این است که یک رابطه foreign key بین جدول Tbl_Order شما و جدول Tbl_Priority شما وجود دارد که یا خود شما و یا همکاران شما آن را در گذشته به وجود آورده اند. وجود این رابطه کلید خارجی SQL Server را ملزم کرده است تا هر گونه عملیاتی را که منجر به اضافه کردن یا ویرایش یک سطر یا سطوری به جدول Tbl_Order می شوند را کنترل کرده، و در صورتی که سطر هایی را که کاربر می خواهد اضافه کند یا ویرایش دهد دارای یک شرایط خاص از پیش تعریف شده مشخصی نباشند، جلوی اضافه کردن آنها را بگیرد. چگونه؟ از طریق تولید خطا و دادن پیغام خطایی که می بینید.

حال، آن شرایط خاص چیست؟

foreign key constraint شما الان دارد به SQL Server می گوید که ستون OrderId جدول Tbl_Order شما با ستون OrderId جدول Tbl_Priority شما دارای یک رابط کلیدای خارجی است. این یعنی چه؟ این یعنی این که SQL Server نباید به هیچ وجه اجازه دهد سطری وارد جدول Tbl_Orders شود که مقدار وارد شده در ستون OrderId آن قبلا در ستون OrderId یکی از سطرهای جدول Tbl_Priority دیده نمی شود. به عبارت دیگر، برای این که یکی از سطرهای جدول Tbl_Orders بتواند یک مقدار خاصی را در ستون OrderId خود داشته باشد، حتما اول باید یک سطر در جدول Tbl_Priority وجود داشته باشد که ستون OrderId اش دارای همان مقدار است.

خوب، این به چه دردی می خورد؟

فرض کنید شما می خواهید آدرس بعضی افراد را در یک جدول به نام Addresses ثبت کنید. یکی از ستون های جدول شما احتمالا ستونی به نام اسم استان (ProvinceName) خواهد بود. شما می خواهید مطمئن باشید که کاربرها نمی توانند استان های اشتباه یا من در آوردی وارد این ستون کنند. مثلا نمی خواهید یک نفر استان آدرسش را استان «چی توز» دکر کند. یک راه جلوگیری از این مسئله این است که شما بیایید و یک جدول درست کنید به اسم Provinces که یک ستون دارد به اسم ProvinceName که در آن، شما اسم تمام استان های کشور را وارد می کنید. بعد، توی جدول Addresses خود، شما می آیید و یک رابطه foreign key constraint بین ستون َAddresses.ProvinceName و ستون Provinces.ProvinceName به وجود می آورید. از آن به بعد، هر زمان یک کاربر سعی می کند مقدار درج شده در ستون ProvinceName هر یک از سطرهای جدول آدرس های شما را تغییر دهد، SQL Server اول می آید و چک می کند که آیا این مقدار وارد شده، این استان وارد شده، در بین استان های لحاظ شده در جدول Provinces دیده می شود و یا خیر. اگر وجود دارد که به سلامت. در غیر این صورت، SQL Server خطایی شبیه همان خطایی را که شما دریافت کردید تولید می کند.

کل این بحث بالا و این مفاهیم برمی گردند به یک مبحث کلی تری به اسم referential integrity که شاید شما این ور و آن ور اسمش را دیده باشید. وازه integrity معنی دست نخورده بودن، تمامیت، سالم بودن، بکارت، صحیح بودن و یکپارچگی را دارد. وازه referential یعنی «مربوط به رابطه ها». اصطلاح referential integrity اشاره می کند به آن دسته از قابلیت ها، توانایی ها و سیاست های SQL Server که دغدغه شان حفاظت از صحت، یکپارچگی و تمامیت رابطه هایی است که بین داده های شما در دیتابیس شما وجود دارد. مثل این رابطه که استان های جدول آدرس ها حتما باید قبلا در جدول استان ها تعریف شده باشند. مبحث foreign key constraints یکی از قوی ترین ابزاری است که SQL Server در اختیار ما می گذارد که در دیتابیس خود referential integrity را حفظ کنیم.

lvlina_r
پنج شنبه 25 شهریور 1389, 16:36 عصر
با تشکر از شما بابت جواب کاملتون ، و اینکه با حوصله من راهنمایی کردید ، ببینید Order_id های جدولی Priority هم باید از همان جایی که Orderid های جدول order آمده گرفته شود ، با این تفاوت که در جدول order ، فیلد orderid می تواند تکراری باشد ، ولی Priority کلید اصلی است ...
ولی اطلاعات ممکن است update شود ، پس به ازای هر update یا insert در جدول saledraft که اطلاعات از آنجا گرفته می شود ، باید ابتدا جدول Priority و سپس جدول order نیز update شود ؟؟
آیا درست متوجه شدم ؟؟ حالا می شه باز راهنماییم کنید که چی کار باید بکنم؟

بهزادصادقی
پنج شنبه 25 شهریور 1389, 16:46 عصر
من دقیقا متوجه مطالب شما نشدم. می شود دو باره توضیج دهید. هر جدول کارش چیست؟ هر جدول را کی در چه زمانی تغییر می دهد؟ ساختار saledraft چیست؟ یک کد OrderId را کی به وجود می آورد؟ اول در کدام جدول وارد می شود؟ وقتی می گویید «باید از همان جایی» منطورتان کدام جاست.

یک مقدار با حوصله بی زحمت بنشیند و با دقت و با جزئیات جامع سیستم را برای ما تشریج کنید. جواب بعد از آن خیلی ساده خواهد شد.