PDA

View Full Version : جلوگیری از وارد نشدن اطلاعات تکراری توی جدول SQL از طریق VB.NET



mah.yar
پنج شنبه 28 دی 1385, 09:45 صبح
فرض کنیم جدولی داریم که توش اطلاعات مربوط به ثبت نام دانشجوست.
با این توصیف اگه کاربر مشخصات دانشجویی را وارد کرد و اون دانشجو قبلا ثبت نام شده بود==> برنامه با نمایش پیامی اطلاعات رو وارد نکند.
اگه میشه دستورشو بنویسید.

programmermp
پنج شنبه 28 دی 1385, 09:59 صبح
سلام

می تونی از این روش استفاده کنی من امتحان کردم مشکلی نداشته

select * From table1 where (stname='ali javadi')

if me.bindingcontext(ds,"table1").count>0 then
msgbox("The student already registered")

که در دستورات بالا table1 نام جدولته

stname نام دانشجو

و ds هم یک متغیر از نوع dataset هست

همین

komail_sh
پنج شنبه 28 دی 1385, 10:04 صبح
شما باید قبل از دستور insert یه select بزنی تا اطلاعات وجود نداشته باشد.
مثال:

datatabel=select name from daneshjoo where name=alipoor
if datatabel.rows.count=0 then
insert into daneshjoo.........
endif

rezaei manesh
پنج شنبه 28 دی 1385, 10:31 صبح
سلام
من مواقعی که اطلاعاتی رو که می خوام چک کنم اگر کلید نباشه (در شبکه اونم) تو همون گرید چک می کنم اگه وجود داشت نمی زارم و دیگر نمی رم تو بانک چک کنم این روش سریعتر هست اما اگه در همان زمان یک کاربر دیگه این اطلاعات رو وارد کرده باشه این هم ثبت می شه
اگه احتمال اینکه این مورد پیش بیاد در برنامه ات کم هست تو همون گراید چک کن وگرنه یه پروسجر بنویس (به کمک دستورات که دوستان نوشتند) و انوجا این کار رو انجام بده.

linux
پنج شنبه 28 دی 1385, 10:47 صبح
یک ایندکس برای جدول درست کنید و آن را uniq تعریف کنید.
این کارهایی که شما انجام مدهید جنگولک بازی هست.

rezaei manesh
پنج شنبه 28 دی 1385, 11:27 صبح
مهندس خوب برای مثال فرض کن می خواد چک کنه ببینه نام x و نام خانوادگی y رو وارد کنه حالا این اطلاعات وارد شده شما می خوای ایندکس رو کدوم بزاری؟! یک فیلد کلید مثل من می گیری و ایندکس رو رو اون می زاری؟

تازه با روش شما کاربر پیغام sql رو می بینه که زیاد جالب نیست فکر می کنه error گرچه برای اون هم راه حل است مثلا شماره خطا رو چک کنی که فکر کنم شما این کار رو می کنید.
به هر حال این یک چیز سلیقه ای هستش فکر کنم البته.

bahramsport
پنج شنبه 28 دی 1385, 11:29 صبح
اگر از sqlserverاستفاده می کنیداز stored procedure استفاده کنید که همونجا تست بشه فکر کنم بهتره - البته index بهترینه

mah.yar
پنج شنبه 28 دی 1385, 13:19 عصر
به هر حال از همه شما ممنونم
جوابمو خیلی خوب گرفتم

linux
پنج شنبه 28 دی 1385, 20:47 عصر
مهندس خوب برای مثال فرض کن می خواد چک کنه ببینه نام x و نام خانوادگی y رو وارد کنه حالا این اطلاعات وارد شده شما می خوای ایندکس رو کدوم بزاری؟! یک فیلد کلید مثل من می گیری و ایندکس رو رو اون می زاری؟

تازه با روش شما کاربر پیغام sql رو می بینه که زیاد جالب نیست فکر می کنه error گرچه برای اون هم راه حل است مثلا شماره خطا رو چک کنی که فکر کنم شما این کار رو می کنید.
به هر حال این یک چیز سلیقه ای هستش فکر کنم البته.
دکتر!
وقتی ایندکس تعریف میکنی فکر کنم تا 16 تا فیلد(شاید هم بیشتر) بتونی با هم ایندکس کنی و این ها را یکتا تعریف کنی فکر کن یک جدول داری به شکل زیر
کد
نام
نام خانوادگی
نام پدر
شماره شناسنامه
می خواهی بر اساس 4 تا فیلد آخر ایندکس کنی
ای دستور ساختن جدول

CREATE TABLE [tbluserNames] (
[ID] [int] NOT NULL ,
[Name] [nvarchar] (50) COLLATE Arabic_CI_AS NULL ,
[Family] [nvarchar] (50) COLLATE Arabic_CI_AS NULL ,
[FatherName] [nvarchar] (50) COLLATE Arabic_CI_AS NULL ,
[IdNumber] [nvarchar] (50) COLLATE Arabic_CI_AS NULL ,
CONSTRAINT [PK_tbluserNames] PRIMARY KEY CLUSTERED
(
[ID]
) ON [PRIMARY]
) ON [PRIMARY]
این هم دستور ساختن ایندکس برای یکتا کردن چندتا فیلد با هم

CREATE UNIQUE INDEX [IX_tbluserNames] ON [dbo].[tbluserNames]([Name], [Family], [FatherName], [IdNumber]) ON [PRIMARY]
بعضی چیزها سلیقه نیست اجبار هست.

rezaei manesh
شنبه 30 دی 1385, 12:37 عصر
خوب حالا که بحث به اینجا کشید بیان بحث ایندکس ها رو کاملتر کنیم.
میدونم که میشه جندتا فیلد رو اینکس کرد مهندس جون!(در ضمن ممنون از دکترای افتخاریت هم که به هم دادی)
قبلا علاوه بر او فیلدی که حتماً باید یکی باشه من چند تا فیلد مهم دیگر رو که جستجو براش داشتم رو هم ایندکس می کردم اما الان دیگه اینکار رو نمی کنم ..
خوب بهترین حالا برای مورد زیر چیه
میانگین رکورد 1000
تعداد فیلد 20
یک فیلد AutoNumber
3فیلد از 20 فیلد بالا بیشتر برای جستجو هست
که 2 تا از این فیلد ها رو هم به کاربر می گیم که نباید تکراری وارد کنه (اگه هم اصرار داشت وارد کنه -در بعضی برنامه ها و فرمها)
فیلد اتو نامبر برای اینه که در ویرایش ها مشکلی نداشته باشیم مجبور نشیم کل دیتابیس رو بگردیم
بهترین روش چیه مهندس

DonetKarvb
شنبه 30 دی 1385, 14:15 عصر
دوستان مبحث ایندکس (Index) و Unique دو چیز جدا هستند. بهتره که اینجا از ;کلمه Uinuqe Constraint استفاده بشه.
شما میتونید کارهای متفاوتی رو انجام بدهید برای این منظور استفاده در استفاده از هر کدام اجباری نیست.
من نوعی به عنوان یک کاربر فقط میخوام که برنامه به من اجازه نده که اطلاعات تکراری وارد کنم. حالا اینکه برنامه نویس چطور میخواد کار کنه به من مربوط نمیشه. و از دید برنامه نویسی هم بابد گفت که شیوه ای انتخاب بشه که ساده و کار آمد باشه. من شخصا" Unique Constarint را ترجیح میدهم چون ما با اینکارمان از قوانین Data Integrity تبعیت کرده ایم.
به دوستمان هم پیشنهاد میکنم که کلیه این عملیات را توسط یک SP که از Transaction برای انجام دستوراتش استفاده میکنه بهره بگیرد. ابتدا tran را باز کنید و بعد چک کیند که این فیلد وجود دارد یا نه سپس در صورت وجود به کاربر(Cilent) پیغام مناسب را ارسال کند و در غیر اینصورت اطلاعات را ثبت کند. استفاده از ساختار Try-Catch و همچنین Service Borker نیز پشنهاد میشود.

DonetKarvb
شنبه 30 دی 1385, 14:27 عصر
دکتر!
وقتی ایندکس تعریف میکنی فکر کنم تا 16 تا فیلد(شاید هم بیشتر) بتونی با هم ایندکس کنی و این ها را یکتا تعریف کنی فکر کن یک جدول داری به شکل زیر
کد
نام
نام خانوادگی
نام پدر
شماره شناسنامه
می خواهی بر اساس 4 تا فیلد آخر ایندکس کنی
ای دستور ساختن جدول

CREATE TABLE [tbluserNames] (
[ID] [int] NOT NULL ,
[Name] [nvarchar] (50) COLLATE Arabic_CI_AS NULL ,
[Family] [nvarchar] (50) COLLATE Arabic_CI_AS NULL ,
[FatherName] [nvarchar] (50) COLLATE Arabic_CI_AS NULL ,
[IdNumber] [nvarchar] (50) COLLATE Arabic_CI_AS NULL ,
CONSTRAINT [PK_tbluserNames] PRIMARY KEY CLUSTERED
(
[ID]
) ON [PRIMARY]
) ON [PRIMARY]این هم دستور ساختن ایندکس برای یکتا کردن چندتا فیلد با هم

CREATE UNIQUE INDEX [IX_tbluserNames] ON [dbo].[tbluserNames]([Name], [Family], [FatherName], [IdNumber]) ON [PRIMARY]بعضی چیزها سلیقه نیست اجبار هست.

دوست عزیز هدق شما از یکتا کردن اینها علاوه بر اینکه ID نیز یکتا میباشد چیست؟
این ایندکس که شما ایجاد کرده اید فضایی را اشغال میکند. که این فضا احتمالا" بیهوده به هدر خواهد رفت فقط برای چک کردن اینکه فیلد تکراری وارد نشود. در حالی که ما میتوانی فقط از همان PK استفاده کنیم. اگر حجم جدوال شما زیاد شود آنگاه یک فاجعه پیش می آید.
در ایجاد ایندکس ها دقت لازم را مبذول فرماید.

rezaei manesh
یک شنبه 01 بهمن 1385, 08:03 صبح
خوب حرف شما کاملا درست در مورد پست آخرتون هم با شما موافقترم
من معمولا disconectedکار می کنم برای وب دقیقا از روش شما استفاده می کنم اما ویندوز نه
چون دستمو می بنده برای مثال من مجبورم مقدار همه فیلد هامو با خودم به پروسیجر ببرم و اگه تکراری بود که هیچی این همه اطلاعات الکی رفت و برگشت (20-30 فیلد مثلا) یا دیگه نمی تونم تو خود دیتا ست کارام رو بکنم یا گاهی در صورت تمایل کاربر باید بتونم که دو تا رکورد رو که فیلد های اصلیشون با هم برابرند وارد کنم(به ندرت برای بعضی از موارد خاص)

linux
یک شنبه 01 بهمن 1385, 17:53 عصر
دوست عزیز هدق شما از یکتا کردن اینها علاوه بر اینکه ID نیز یکتا میباشد چیست؟
این ایندکس که شما ایجاد کرده اید فضایی را اشغال میکند. که این فضا احتمالا" بیهوده به هدر خواهد رفت فقط برای چک کردن اینکه فیلد تکراری وارد نشود. در حالی که ما میتوانی فقط از همان PK استفاده کنیم. اگر حجم جدوال شما زیاد شود آنگاه یک فاجعه پیش می آید.
در ایجاد ایندکس ها دقت لازم را مبذول فرماید.

ALTER TABLE [dbo].[tbluserNames] ADD CONSTRAINT [IX_tbluserNames] UNIQUE NONCLUSTERED
(
[Name],
[Family],
[FatherName],
[IdNumber]
) ON [PRIMARY]
GO

بجای ایندکس می تونی CONSTRAINT استفاده کنی مثل مثال بالا در هر صورت مطمین باشید همون چندتا فیلدی که باید منحصر بفرد باشند بهتر هست که ایندکس هم بشوند هیچ مشکلی هم پیش نمی آید ، اصلا هم نگران اندازه فایل خودتان نباشید

linux
یک شنبه 01 بهمن 1385, 17:56 عصر
خوب حالا که بحث به اینجا کشید بیان بحث ایندکس ها رو کاملتر کنیم.
میدونم که میشه جندتا فیلد رو اینکس کرد مهندس جون!(در ضمن ممنون از دکترای افتخاریت هم که به هم دادی)
قبلا علاوه بر او فیلدی که حتماً باید یکی باشه من چند تا فیلد مهم دیگر رو که جستجو براش داشتم رو هم ایندکس می کردم اما الان دیگه اینکار رو نمی کنم ..
خوب بهترین حالا برای مورد زیر چیه
میانگین رکورد 1000
تعداد فیلد 20
یک فیلد AutoNumber
3فیلد از 20 فیلد بالا بیشتر برای جستجو هست
که 2 تا از این فیلد ها رو هم به کاربر می گیم که نباید تکراری وارد کنه (اگه هم اصرار داشت وارد کنه -در بعضی برنامه ها و فرمها)
فیلد اتو نامبر برای اینه که در ویرایش ها مشکلی نداشته باشیم مجبور نشیم کل دیتابیس رو بگردیم
بهترین روش چیه مهندس
الان نمی دانم مشکلت چی هست؟ 1000 تا که اصلا رقمی نیست. ایندکس هم بکن برای یونیک بودن یا از unique index یا از CONSTRAINT

DonetKarvb
یک شنبه 01 بهمن 1385, 23:38 عصر
ALTER TABLE [dbo].[tbluserNames] ADD CONSTRAINT [IX_tbluserNames] UNIQUE NONCLUSTERED
(
[Name],
[Family],
[FatherName],
[IdNumber]
) ON [PRIMARY]
GO
بجای ایندکس می تونی CONSTRAINT استفاده کنی مثل مثال بالا در هر صورت مطمین باشید همون چندتا فیلدی که باید منحصر بفرد باشند بهتر هست که ایندکس هم بشوند هیچ مشکلی هم پیش نمی آید ، اصلا هم نگران اندازه فایل خودتان نباشید

به شما پیشنهاد میکنم بروید و کمی در مورد ایندکس ها و انواع آن و همچنین Constraint ها و انواع آن مطالعه کنید.
این نکته را متذکر میشوم که وجود ایندکس های بیهوده حداقل باعث افت سرعت insert و Update میشوند. در ضمن هدف از ایندکس بالا بردن سرعت کوئری هاست نه یکتا کردن و کار های دیگر.

problem
یک شنبه 01 بهمن 1385, 23:46 عصر
در یک تجربه، من یک SP‌ نوشتم که کار INSERT رو انجام بده. توش چک می‌کرد، اگر فیلد تکراری بود یک ۱۰۰- بر می‌گردوند، و اگر نه یک ۱۰۰+ بر می‌گردوند! برای کار من کفایت می‌کرد، برام جنبه آموزشی هم داشت.