PDA

View Full Version : Update کردن یک جدول بدون فیلد کلید



first_squit
پنج شنبه 10 آبان 1386, 13:56 عصر
با سلام خدمت دوستان عزیز

من یک DataGrideVeiw دارم که اطلا عات در آن نمایش داده می شه می خوام اطلاعاتی رو که نمایش داده شده کاربر بتوانه اطلاعات رو ویرایش کنه و بعد اطلاعات ویرایش شده Update بشن

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

آیا این کار امکان داره یا نه !!!!!!!!!

اَرژنگ
پنج شنبه 10 آبان 1386, 14:48 عصر
۱) اگر میتوانید فیلد کلید اضافه کنید خودتان را راحت کنید
۲) اصلا این نوع جدول درست نیست، اگر شما چند تا رویه یکسان داشته باشید کدام باید آٓپدیت بشه.
۳) به فرض اگر هم ممکن باشد، مشکلات شما از آپدیت کردن این جدول خیلی بیشتر است، جدولتان را به هر حال باید درست کنید، اضافه کردن یک فیلد کلید راحت تر از اینه که با آدامس و چوب کبریت یک جواب سرهم کنیم.

hassan razavi
پنج شنبه 10 آبان 1386, 15:19 عصر
منهم با ارژنگ خان موافقم. هرچه سریعتر حداقل یک فیلد AutoNumber به جدول تون اضافه کنید و خودتون را راحت کنید

first_squit
پنج شنبه 10 آبان 1386, 15:34 عصر
۱) اگر میتوانید فیلد کلید اضافه کنید خودتان را راحت کنید
۲) اصلا این نوع جدول درست نیست، اگر شما چند تا رویه یکسان داشته باشید کدام باید آٓپدیت بشه.
۳) به فرض اگر هم ممکن باشد، مشکلات شما از آپدیت کردن این جدول خیلی بیشتر است، جدولتان را به هر حال باید درست کنید، اضافه کردن یک فیلد کلید راحت تر از اینه که با آدامس و چوب کبریت یک جواب سرهم کنیم.
من هم خودم متوجه هستم اما متاسفانه این جداول نمی تونه فیلد کلید داشته باشه

به هر حال متشکر م

first_squit
پنج شنبه 10 آبان 1386, 15:36 عصر
منهم با ارژنگ خان موافقم. هرچه سریعتر حداقل یک فیلد AutoNumber به جدول تون اضافه کنید و خودتون را راحت کنید
با این موافقم
متشکرم اصلآ یادم نبود

PC2st
پنج شنبه 10 آبان 1386, 21:08 عصر
بطور معمول برای آپدیت (Update) کردن اطلاعات موجود در DataTable، نیازی به Primary Key یا Auto Number نیست.

اَرژنگ
جمعه 11 آبان 1386, 04:08 صبح
بطور معمول برای آپدیت (Update) کردن اطلاعات موجود در DataTable، نیازی به Primary Key یا Auto Number نیست.
پس به چی نیاز است؟ (البته اگر با اصول درست برنامه نویسی کار کنیم)؟

PC2st
جمعه 11 آبان 1386, 11:07 صبح
مثلا برای جدولی که دو فیلد FName و LName رو داره، میشه خاصیت SqlDataAdapter.UpdateCommand رو شبیه به زیر تنظیم کرد (استفاده از SourceVersion):


this.da.UpdateCommand = new SqlCommand ("UPDATE Table1 SET FName = @FName, LName = @LName WHERE FName = @preFName AND LName = @preLName", cn);
this.da.UpdateCommand.Parameters.Add ("@FName", SqlDbType.VarChar, 20, "FName");
this.da.UpdateCommand.Parameters.Add ("@LName", SqlDbType.VarChar, 20, "LName");
this.da.UpdateCommand.Parameters.Add ("@preFName", SqlDbType.VarChar, 20, "FName").SourceVersion = DataRowVersion.Original;
this.da.UpdateCommand.Parameters.Add ("@preLName", SqlDbType.VarChar, 20, "LName").SourceVersion = DataRowVersion.Original;

choobin84
جمعه 11 آبان 1386, 12:43 عصر
بطور معمول برای آپدیت (Update) کردن اطلاعات موجود در DataTable، نیازی به Primary Key یا Auto Number نیست.
نه تنها به طور معمول ، حتی در شرایط خاص هم می توان بدون آنکه فیلدی را primary تعریف کنیم، آنرا primary‌در نظر بگیریم.


پس به چی نیاز است؟ (البته اگر با اصول درست برنامه نویسی کار کنیم)؟

اصول درست برنامه نویسی اینه که در جدولی که کلید داریم ، نباید رکورد تکراری وجود داشته باشه، حالا این وظیفه را که تشخیص رکوردی تکراری هست یا نه را یا برنامه نویس باید انجام بده یا SQL ، که در صورتی که باید SQL این کار را انجام بدهد، در جدول فیلد را Primary می کنیم.

اما در واقع دو حالت بیشتر نداریم،
یا جدول می تواند فیلد (یا مجموعه ای از چند فیلد) را ، به عنوان کلید بپذیرد (نیاز به گذاشتن علامت کلید در کنار فیلد ها نیست، چون خود به خود منحصر بفرد هستند.) که در اینصورت کافیه که منحصر بفرد باشه. (از طریق کد نویسی رکورد توسط برنامه نویس شناسایی بشه یا توسط SQL)

یا جدول این امکان را برای هیچ کدام از فیلد ها ندارد. هیچ کدام از فیلد ها (یا مجموعه ای از فیلدها) منحصر بفرد نیستند.

در مورد اول ، اگر جدولی یک فیلد منحصر بفرد داشته باشد، خود به خود کلید است. (منظور از منحصر بفرد بودن آن فیلد این است که رکوردی با صفات مشابه نداشته باشیم.) در این حالت می توان مثلا به پایگاه داده sql‌اعلام کرد ، من فلان فیلد را به عنوان کلید در نظر گرفته ام و پایگاه داده SQL شما اجازه نداری بیش از یک رکورد با مشخصات کلیدی که برایت تعریف کردم داشته باشی. اینجا کار برنامه نویسی من راحت می شود. چون نیازی نیست بیایم جدول را قبل از هرگونه تغییری (درج و آپ دیت) بررسی کنم که رکورد با فیلد کلید تکراری نداشته باشد.
اما اگر به پایگاه داده SQL هیچ فیلدی را به عنوان کلید معرفی نکنم ، باید در برنامه این امکان را گنجانده باشم که رکورد تکراری در جدول درج نشود.
نکته؛ توجه داشته باشیم رکورد تکراری می تواند در جدول درج شود، در صورتی که کلید را به SQL معرفی نکرده باشیم.(علامت کلید را برای فیلد در هنگام طراحی جدول نزده باشیم.)

اگر جدولی به هیچ عنوان فیلد کلید ندارد نه تکی و نه مجموعه ای از چند فیلد نمی توانند کلید باشند. در این صورت هم هیچ مشکلی پیش نمی آید. رکوردهای تکراری می توانند در جدول درج شوند. اما سئوال اینجاست، اگر بخواهیم از مجموع مثلا 6 تا رکورد که تمام فیلد های آن مقادیر یکسانی دارند فقط رکورد دوم را آپ دیت کنیم آنوقت چه؟
اصولا در ان هنگام رکورد تکراری معنا ندارد. در واقع جدول به این شکل یک افزونگی دارد. اون 6 تا رکورد تکراری دقیقا یک رکورد هستند.
اگر طبق اصول ریاضیات بخواهیم مساله را در نظر بگیریم، عضو تکراری در هر مجموعه ای بی اثر است. مثلا {1,2,33,33,2,2,1,} ={1,2,33}

این اصل اینجا هم صادق است . در واقع این رکورد های تکراری باید یک چیزی داشته باشند که آنها را از هم جدا کند (که می شود کلید) یا نداشته باشند.(هر جدول یک مجموعه است)
بی معنی است بگوییم که از اون 6 تا رکورد یکیشون با بقیه فرق می کنه ولی تمام خصوصیات مشابه داشته باشند.

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

choobin84
جمعه 11 آبان 1386, 12:45 عصر
مثلا برای جدولی که دو فیلد FName و LName رو داره، میشه خاصیت SqlDataAdapter.UpdateCommand رو شبیه به زیر تنظیم کرد (استفاده از SourceVersion):


this.da.UpdateCommand = new SqlCommand ("UPDATE Table1 SET FName = @FName, LName = @LName WHERE FName = @preFName AND LName = @preLName", cn);
this.da.UpdateCommand.Parameters.Add ("@FName", SqlDbType.VarChar, 20, "FName");
this.da.UpdateCommand.Parameters.Add ("@LName", SqlDbType.VarChar, 20, "LName");
this.da.UpdateCommand.Parameters.Add ("@preFName", SqlDbType.VarChar, 20, "FName").SourceVersion = DataRowVersion.Original;
this.da.UpdateCommand.Parameters.Add ("@preLName", SqlDbType.VarChar, 20, "LName").SourceVersion = DataRowVersion.Original;


کاملا درسته.
این درحالتی است که مجموعه مقادیر فیلد ها ، در یک رکورد یک کلید را تشکیل می دهند.
بی معنی است بگوییم که دو رکورد مشابه داریم و فقط می خواهیم یکیشان را آپ دیت کنیم.

choobin84
جمعه 11 آبان 1386, 13:12 عصر
من هم خودم متوجه هستم اما متاسفانه این جداول نمی تونه فیلد کلید داشته باشه


چرا؟
امیدوارم دوباره به این تایپیک یه سر بزنید ، نمونیم بمونیم تو خماری که چرا نمیشه فیلد کلید توی جدول داشت.

برخی دوستان autonumber را پیشنهاد کرده بودند. توجه داشته باشیم که اگر جدولی را در نظر بگیریم که می توان مجموعه چند فیلد را کلید کنیم(مجوع مقادیرشان رکورد منحصر بفرد بسازند)، در جدول افزونگی به بار نمیاد. نمی خام بگم کار برنامه نویس با AutoNumber راحتتر نیست. مهم اینه که جدول چیزایی که لازم نداره رو بهش اضافه نکنیم

first_squit
جمعه 11 آبان 1386, 14:57 عصر
چرا؟
امیدوارم دوباره به این تایپیک یه سر بزنید ، نمونیم بمونیم تو خماری که چرا نمیشه فیلد کلید توی جدول داشت.

برخی دوستان autonumber را پیشنهاد کرده بودند. توجه داشته باشیم که اگر جدولی را در نظر بگیریم که می توان مجموعه چند فیلد را کلید کنیم(مجوع مقادیرشان رکورد منحصر بفرد بسازند)، در جدول افزونگی به بار میاد. نمی خام بگم کار برنامه نویس راحتتر نیست. مهم اینه که جدول چیزایی که لازم نداره رو بهش اضافه نکنیم
دوست عزیز تو برنامه ای که من نوشتم هر کاربر دارای یک شماره یکتا می باشد در داخل یکی از جد ول های قرار گرفته در بانک اطلاعاتی این امکان وجود داره که هر کاربر می تونه چندین رکورد در داخل اون درج کنه

حالا در یک بخش دیگر که برای ویرایش اطلا عات طراحی شده من می خوام اطلاعات وارد شده رو ویرایش کنم همانطور که دوستان راهنمایی کردند می شه در شرط Update چند فیلد رو قرار داد و من هم همینکارو کردم .

مشکل حل شد

PC2st
جمعه 11 آبان 1386, 15:31 عصر
نکته مفید و سودمندی ارائه کردید... :-)
در صورت وجود داده های تکراری، در واقع هویت آنها هم یکی است.
مثلا در همان آرایه ای که ذکر شد:


{1, 2, 33, 33, 2, 2, 1}

در واقع اینطور در نظر بگیریم که 7 داده نداریم، تنها 3 داده داریم که بعضی از آنها چند بار تکرار شده اند، پس به طبع، در صورت تغییر یافتن یکی از آنها، طبیعی است که تمام موارد تکرار شده هم تغییر یابد.


نه تنها به طور معمول ، حتی در شرایط خاص هم می توان بدون آنکه فیلدی را primary تعریف کنیم، آنرا primary‌در نظر بگیریم.
منظورتون Unique Key است؟


این درحالتی است که مجموعه مقادیر فیلد ها ، در یک رکورد یک کلید را تشکیل می دهند.
بی معنی است بگوییم که دو رکورد مشابه داریم و فقط می خواهیم یکیشان را آپ دیت کنیم.
در واقع نمیگوییم که دو رکورد مشابه داریم، بلکه دو رکورد تکراری داریم که هر دوی آنها را آپدیت میکنیم (رکوردی که بی خود و بی جهت، 2 بار تکرار شده است).

برای جلوگیری از تکرار راه حلی مثل Primary Key در همه موارد بطور کامل چاره ساز نیست، بعنوان مثال جدولی با فیلدهای ID و Name رو در نظر بگیرید که فیلد ID بصورت Primary Key لحاظ شده است. حالا دو رکورد رو در نظر بگیرید که دارای Name یکسان و ID های متفاوتی باشند (!) مثل شخصی که دوبار در جایی ثبت نام میکند (Name) در حالی که هویت های متفاوتی دارد (ID) مثل افرادی در این سایت که با دو ID در این سایت ثبت نام میکنند! یعنی خلاف مقررات :-) مثلا:


ID Name City AGE
-----------------------------
023400 John USA 22
099999 John USA 22
111111 John USA 22
421267 John USA 22

این حالت مانند همان آرایه ی مذکور است که بعضی از اعداد چندبار تکرار شده بودند با این تفاوت که در صورت وجود فیلد ID در جدول، یک کاربر با دو هویت متفاوت میتواند ثبت نام کند (تکراری بودن ثبت نام یک کاربر)، در حالیکه اگر فیلد ID وجود نداشت، کاربر دوبار ثبت نام میکرد ولی تنها دارای یک هویت خواهد بود بطوری که هویتهای او تکرار شده است. برای جلوگیری از تکرار هم راههای مختلفی وجود دارد. قبول دارم این استدلال ار جهاتی درست و جهاتی نادرست است.

همانطور که میدونید Primary Key برای ایجاد جداول رابطه ای کاربرد دارد و روی فیلدهای از نوع عددی (مثل Auto Number) تعریف میشود (عدد بخاطر حجم کمتر و سرعت بیشتر). در نهایت این رو میخواستم بگم که برای Update کردن داده های DataTable حتما نیازی به یک فیلد جداگانه (جدید) تحت عنوان Auto Number یا Primary Key نیست. یعنی لازم نیست که حتما یک فیلد جدیدی تحت عنوان ID اضافه کنیم، بلکه توسط Enum ای بنام SourceVersion میتوان به مقدار قبلی داده ها (قبل از ویرایش) دسترسی داشت :-)

میشه با توجه به توضیحاتی که اشاره داشتید، مانع از وجود رکوردهای تکراری شد یا فیلدی مثل Name رو بصورت Unique Key مشخص کرد.

choobin84
جمعه 11 آبان 1386, 15:51 عصر
نکته مفید و سودمندی ارائه کردید... :-)
در صورت وجود داده های تکراری، در واقع هویت آنها هم یکی است.
مثلا در همان آرایه ای که ذکر شد:


{1, 2, 33, 33, 2, 2, 1}
در واقع اینطور در نظر بگیریم که 7 داده نداریم، تنها 3 داده داریم که بعضی از آنها چند بار تکرار شده اند، پس به طبع، در صورت تغییر یافتن یکی از آنها، طبیعی است که تمام موارد تکرار شده هم تغییر یابد.


منظورتون Unique Key است؟


در واقع نمیگوییم که دو رکورد مشابه داریم، بلکه دو رکورد تکراری داریم که هر دوی آنها را آپدیت میکنیم (رکوردی که بی خود و بی جهت، 2 بار تکرار شده است).

برای جلوگیری از تکرار راه حلی مثل Primary Key در همه موارد بطور کامل چاره ساز نیست، بعنوان مثال جدولی با فیلدهای ID و Name رو در نظر بگیرید که فیلد ID بصورت Primary Key لحاظ شده است. حالا دو رکورد رو در نظر بگیرید که دارای Name یکسان و ID های متفاوتی باشند (!) مثل شخصی که دوبار در جایی ثبت نام میکند (Name) در حالی که هویت های متفاوتی دارد (ID) مثل افرادی در این سایت که با دو ID در این سایت ثبت نام میکنند! یعنی خلاف مقررات :-) مثلا:


ID Name City AGE
-----------------------------
023400 John USA 22
099999 John USA 22
111111 John USA 22
421267 John USA 22
این حالت مانند همان آرایه ی مذکور است که بعضی از اعداد چندبار تکرار شده بودند با این تفاوت که در صورت وجود فیلد ID در جدول، یک کاربر با دو هویت متفاوت میتواند ثبت نام کند (تکراری بودن ثبت نام یک کاربر)، در حالیکه اگر فیلد ID وجود نداشت، کاربر دوبار ثبت نام میکرد ولی تنها دارای یک هویت خواهد بود بطوری که هویتهای او تکرار شده است. برای جلوگیری از تکرار هم راههای مختلفی وجود دارد. قبول دارم این استدلال ار جهاتی درست و جهاتی نادرست است.

همانطور که میدونید Primary Key برای ایجاد جداول رابطه ای کاربرد دارد و روی فیلدهای از نوع عددی (مثل Auto Number) تعریف میشود (عدد بخاطر حجم کمتر و سرعت بیشتر). در نهایت این رو میخواستم بگم که برای Update کردن داده های DataTable حتما نیازی به یک فیلد جداگانه (جدید) تحت عنوان Auto Number یا Primary Key نیست. یعنی لازم نیست که حتما یک فیلد جدیدی تحت عنوان ID اضافه کنیم، بلکه توسط Enum ای بنام SourceVersion میتوان به مقدار قبلی داده ها (قبل از ویرایش) دسترسی داشت :-)

میشه با توجه به توضیحاتی که اشاره داشتید، مانع از وجود رکوردهای تکراری شد یا فیلدی مثل Name رو بصورت Unique Key مشخص کرد.

آرایه نه، مجموعه. مجموعه است که همچین خصوصیتی داره، آرایه یعنی اگر عضو یکم 1 بود و عضو پنجم هم 1 بود ، دو تا چیز متفاوتند.

استدلال از چه جهتی نادرسته؟.

PC2st
جمعه 11 آبان 1386, 16:03 عصر
استدلال از جهتی میتونه نادرست باشه که فیلد Name همیشه جزء هویت به حساب نمیاد و گاهی فیلدی مثل ID خودش یک هویت میتونه باشه مثل خرید بلیط (Ticket)، که هر فرد میتونه چندین بلیط بخره. در حقیقت تکراری بودن یا تکراری نبودن یک رکورد، به کاربرد فیلدها بستگی داره :-)

choobin84
یک شنبه 13 آبان 1386, 05:47 صبح
کلیدها؛
در مدل رابطهای چند کلید داریم:
1- ابر کلید
2- کلید کاندید
3- کلید اصلی
4- کلید دیگر (بدیل)
5- کلید خارجی

ابر کلید؛
هر زیرمجموعه ای (ترکیبی) از اسامی صفات رابطه (جدول) که در هیچ دو تاپل مقدار یکسان ندارد.

کلید کاندید؛
هر زیرمجموعه (ترکیبی) از مجموعه اسامی صفات رابطه (جدول) که 2 خاصیت داشته باشد:
الف - یکتایی مقدار داشته باشد
ب – کاهش ناپذیر باشد
(کاهش ناپذیری: اگر یکی از عناصر این مجموعه را حذف کنیم، زیر مجموعه باقیمانده دیگر خاصیت یکتایی مقدار نداشته باشد)

نکته؛ هر ابر کلید، کلید کاندید نیست(چون ممکن است کاهش ناپذیر نباشد)، اما هر کلید کاندید، یک ابر کلید است.

سئوال؛ آیا وجود حداقل یک کلید کاندید در رابه تضمین است؟ جواب ، بله.زیرا در بدترین حالت با ترکیب تمام صفات رابطه به همن مجموعه عنوان (صفات) می رسیم که طبق تعریف رابطه یکتایی مقدار دارد.(منظور این مثال است {33و33و33و2و1و1}={33و2و1} )

کلید اصلی؛
یکی از کلید های کاندید که طراح(برنامه نویس یا طراح بانک اطلاعاتی) آنرا انتخاب می کند و به سیستم معرفی می کند.معمولا کلید کاندیدی که طول کوتاهتری داشته باشد، انتخاب می شود.

کلید دیگر(بدیل)؛
هر کلید کاندید ، غیر از کلید اصلی ، کلید دیگر نام دارد.

کلید خارجی؛
کلید خارجی، صفت ساده یا مرکبی است که از ک میدان کاندید (یا میدان اصلی) مقدار بگیرد و می تواند همنام و یا نا همنام با کلید کاندید باشد.
کلید خارجی برای نمایش ارتباطات بین انواع موجودیت ها(جداول) به کار می رود.

choobin84
یک شنبه 13 آبان 1386, 05:55 صبح
استدلال از جهتی میتونه نادرست باشه که فیلد Name همیشه جزء هویت به حساب نمیاد و گاهی فیلدی مثل ID خودش یک هویت میتونه باشه مثل خرید بلیط (Ticket)، که هر فرد میتونه چندین بلیط بخره. در حقیقت تکراری بودن یا تکراری نبودن یک رکورد، به کاربرد فیلدها بستگی داره :-)

استدلال درسته. اما ممکنه کامل نباشه.
بحثی که من ارائه دادم در مورد کلیدها بود. نه نرمال سازی. بله مانند مثال شما اینطوری نباید باشد. این جدول احتیاج به نرمالسازی دارد.

نکته؛ نرمالسازی را برای ساده کردن کار خودمان انجام می دهیم و هیچ دلیل و منطق تئوری ندارد. شما به هر تعداد که بخواهید در عمل می توانید در بانک اطلاعات داده های تکراری وارد کنید و این از نظر تئوریک منافات ندارد ، اما نکته ای که هست اینه، که کار برنامه مدیریت پایگاه داده ها را در ذخیره و بازیابی اطلاعات هجو سخت کرده ایم.


دوست عزیز تو برنامه ای که من نوشتم هر کاربر دارای یک شماره یکتا می باشد در داخل یکی از جد ول های قرار گرفته در بانک اطلاعاتی این امکان وجود داره که هر کاربر می تونه چندین رکورد در داخل اون درج کنه


این جدول کلید کاندید دارد، شما مجموعه ای را انتخاب کرده اید که در جدو رکوردهای آن یکتایی مقدار دارند. یعنی کلید کاندید در آن هست. پس نگید که کلید توی اون نیست.