PDA

View Full Version : بررسی یک رکورد در دیتابیس



ironman
دوشنبه 07 دی 1388, 12:40 عصر
سلام دوستان... چطوری میتونم وجود یه رکورد رو داخل دیتابیس با مقداری که از یه textbox میگیریم تشحیص بدیم ...؟؟؟ یعنی اگه وجود داشت error بده و اگه نداشت ثبت کنه داخل دیتابیس

mehdi.mousavi
دوشنبه 07 دی 1388, 12:58 عصر
سلام دوستان... چطوری میتونم وجود یه رکورد رو داخل دیتابیس با مقداری که از یه textbox میگیریم تشحیص بدیم ...؟؟؟ یعنی اگه وجود داشت error بده و اگه نداشت ثبت کنه داخل دیتابیس

سلام.
خوب، این نشون میده مقدار مزبور در بانک باید Unique باشه. وقتی شما چنین Constraint ای رو روی فیلد مزبور تعیین کنید، هنگام عمل Insert، اگر فیلد مزبور از قبل وجود داشته باشه، عمل Insert با Exception مواجه میشه و شما میتونید با گرفتن SqlException مربوطه، روند مورد نظر در کدتون رو دنبال کنید.

برای آشنایی با نحوه ایجاد Constraint ها، Unique Key ها، PK ها و ... به BOL مایکروسافت رجوع کنید (http://msdn.microsoft.com/en-us/library/ms130214.aspx) (در صورتیکه از SQL Server استفاده می کنید).

موفق باشید.

Behrouz_Rad
دوشنبه 07 دی 1388, 13:29 عصر
هنگام عمل Insert، اگر فیلد مزبور از قبل وجود داشته باشه، عمل Insert با Exception مواجه میشه و شما میتونید با گرفتن SqlException مربوطه، روند مورد نظر در کدتون رو دنبال کنید.

این کار صحیح نیست. نباید به عمد باعث بروز خطا در برنامه شد. حتماً می دونی که وقوع خطا در try catch سربار به برنامه تحمیل می کنه. تا حد ممکن باید عوامل بروز خطا رو با دستورات برنامه بررسی کنی.
روش صحیح می تونه به شکل ذیل باشه:



IF NOT EXISTS(SELECT myField FROM myTable WHERE myField = 'ye chizi')
BEGIN
INSERT INTO myTable(myField) VALUES('do chizi')
END

مقدار برگشتی SP می تونه IDENTITY@@ از طریق یک پارامتر OUTPUT باشه.

موفق باشید.

clover
دوشنبه 07 دی 1388, 13:41 عصر
در مورد روشی که آقای بهروز راد فرمودند، اگر رکورد وجود داشته باشه دوباره ثبت نمیشه اما ما چطور می تونیم از وجود رکورد مطلع بشیم، یعنی اخطاری هم مبنی بر وجود رکورد به کاربر بدیم ؟

Behrouz_Rad
دوشنبه 07 دی 1388, 14:04 عصر
در مورد روشی که آقار بهروز راد فرمودند، اگر رکورد وجود داشته باشه دوباره ثبت نمیشه اما ما چطور می تونیم از وجود رکورد مطلع بشیم، یعنی اخطاری هم مبنی بر وجود رکورد به کاربر بدیم ؟
در خط آخر پست قبل نوشتم که:


مقدار برگشتی SP می تونه IDENTITY@@ از طریق یک پارامتر OUTPUT باشه.

mehdi.mousavi
دوشنبه 07 دی 1388, 14:30 عصر
این کار صحیح نیست. نباید به عمد باعث بروز خطا در برنامه شد. مقدار برگشتی SP می تونه IDENTITY@@ از طریق یک پارامتر OUTPUT باشه. موفق باشید.

سلام.
من با فرمایش شما (از دید کلی) موافقم، اما این نباید باعث بشه که از تعریف Constraint مزبور روی فیلد (در سطح بانک) صرف نظر بشه (البته گرفتن این تصمیم هم به شرایط دیگه ای بستگی داره).

حالا فرض کنیم کاری که شما گفتید رو انجام بدیم. ما خواه و ناخواه باید برای Error هایی که SQL Server ممکنه Generate کنه، آماده باشیم پس حتما Framework ای برای تعامل با اونها در سیستم خودمون در نظر خواهیم گرفت. حالا فرض کنید عمل Insert قرار بود دو فیلد متفاوت رو touch کنه که هر دو هم بنا به نیاز باید Unique باشن. اونوقت شما چطور میخواهید Error Handling رو انجام بدید؟ در اینصورت شما مجبورید تا دو پارامتر خروجی روی SP تعریف کنید و کد مورد نظر رو به Client برگردونید. اما مساله اینجا ختم نمیشه. حالا نیاز به ساز و کاری داریم تا این اعداد رو به "عبارات قابل فهم" توسط کاربر تبدیل کنه، پس یک Mapping هم اینجا نیاز داریم.

حالا یه قدم پیشتر بریم. فرض کنید که SP شما پیچیده تر از این حرفها باشه، و قرار باشه چند عمل متفاوت رو (نه لزوما Insert) در بانک و جداول متفاوت انجام بده. اینجا رو چیکار کنیم؟ آیا باید تعداد پارامترهای خروجی SP رو افزایش بدیم و ...؟ تازه، اینجا باید اطلاعات بیشتری به Client برگردونیم، اطلاعاتی از قبیل اینکه کدوم جدول باعث بوجود اومدن خطا شده، خطا بابت چه Operation بوده و و و ...

این، بنظر من یک Exception هستش... اگر میشد قبل از رسیدن به سطح بانک از اون پیشگیری کرد، باید اینکار انجام بشه. من نمیگم استفاده از EXISTS نباید در SP مزبور وجود داشته باشه، اما اگر قراره بواسطه اینکار، دو Framework متفاوت برای تعامل با خطاها، در دو نقطه از سیستم پیاده سازی بشه، اینکار کاملا با فلسفه Lean & Agile در تضاده... در هر حال، همه اینها به سیستمی داره که در حال توسعه اون هستیم...

در مورد استفاده از @@IDENTITY برای گرفتن ID آخرین رکورد Insert شده در بانک هم باید بگم این روش صحیح نیست. بهتره از SCOPE_IDENTITY() برای این منظور استفاده بشه... این دو، دو Scope متفاوت در برگردوندن Identity ها دارن.

موفق باشید.

Behrouz_Rad
دوشنبه 07 دی 1388, 15:48 عصر
حالا فرض کنیم کاری که شما گفتید رو انجام بدیم. ما خواه و ناخواه باید برای Error هایی که SQL Server ممکنه Generate کنه، آماده باشیم پس حتما Framework ای برای تعامل با اونها در سیستم خودمون در نظر خواهیم گرفت. حالا فرض کنید عمل Insert قرار بود دو فیلد متفاوت رو touch کنه که هر دو هم بنا به نیاز باید Unique باشن. اونوقت شما چطور میخواهید Error Handling رو انجام بدید؟ در اینصورت شما مجبورید تا دو پارامتر خروجی روی SP تعریف کنید و کد مورد نظر رو به Client برگردونید. اما مساله اینجا ختم نمیشه. حالا نیاز به ساز و کاری داریم تا این اعداد رو به "عبارات قابل فهم" توسط کاربر تبدیل کنه، پس یک Mapping هم اینجا نیاز داریم.

این که واضحه. اگر با Reflector به کدهای دات نت نگاه کنی، خطاها از Resourse خونده میشن. Mapping متداولترین کاری هست که انجام میشه. خطاهای برگشتی مختص SP را در یک فایل XML قرار بده و برای هر کدوم هم توضیح خاص خودش رو بنویس. با XML Serialization & Deserialization، فایل XML رو به Object تبدیل کن و let's go ;)


حالا یه قدم پیشتر بریم. فرض کنید که SP شما پیچیده تر از این حرفها باشه، و قرار باشه چند عمل متفاوت رو (نه لزوما Insert) در بانک و جداول متفاوت انجام بده. اینجا رو چیکار کنیم؟ آیا باید تعداد پارامترهای خروجی SP رو افزایش بدیم و ...؟ تازه، اینجا باید اطلاعات بیشتری به Client برگردونیم، اطلاعاتی از قبیل اینکه کدوم جدول باعث بوجود اومدن خطا شده، خطا بابت چه Operation بوده و و و ...

نیازی نیست که تعداد پارامترهای خروجی رو تغییر بدی. یک پارامتر کفایت می کنه. در نظر بگیر. که دو عملیات پشت سر هم قرار هست انجام بشن. عملیات اول با مشکل مواجه میشه و Catch اون اتفاق میفته. آیا کنترل اجرای برنامه به عمل دوم میرسه که Catch مختص اون رخ بده؟ مسلماً اینطور نیست. پس اولین خطا برای جلوگیری از اجرای دومین دستور کافیه.


این، بنظر من یک Exception هستش

ما به سناریوی حال نگاه می کنیم. نیاز نیست قضیه رو اینقدر پیچیده کنی و با فرض های مختلف پیش بری. مسئله ساده تر از این حرف هاست. سناریوهای مختلف، روش های مختلفی رو می طلبن.


در مورد استفاده از @@IDENTITY برای گرفتن ID آخرین رکورد Insert شده در بانک هم باید بگم این روش صحیح نیست. بهتره از SCOPE_IDENTITY() برای این منظور استفاده بشه... این دو، دو Scope متفاوت در برگردوندن Identity ها دارن.

باز هم به پاراگراف قبلیم ارجاعت میدم. SCOPE_IDENTITY برای زمانی خوب هست که Trigger داری اما در حالت کلی، استفاده از SCOPE_IDENTITY بهتر از IDENTITY@@ هست.

موفق باشید.