PDA

View Full Version : مشکل Identity و GridView



hmm
یک شنبه 10 تیر 1386, 12:37 عصر
سلام
فرضا اگه یه جدول چکها داشته باشیم بصورت زیر


chq_id
chq_bank_type
chq_bank_branch
chq_bank_account
chq_amnt
chq_contract_idکه فیلد آخر یک کلید خارجی به جدول پیمانکاران است که مشخص میکند یک چک خاص مربوط به چه پیمانکاری است
حال اگه فرمی داشته باشیم که فقط بخواهد چکهای یک پیمانکار رو نمایش بده و بشه تو اون فرم از طریق GridView هم بشه چک جدید وارد بشه به دلیل Identity بودن فیلد Chq_ID آخرین شماره ID چگونه تشخیص داده میشه؟
به عبارت دیگه فرم من با استفاده از dataset چکهای یک پیمانکار رو استخراج میکنه و به gridبایند میشه تا اینجا مشکلی نیست ولی اگه بخوام چک جدید وارد کنم شماره ستون Chq_ID یکی بیشتر از آخرین Id چکهای فیلتر شده است نه آخرین شماره Id واقعی چک و در نهایت بعد از اجرای متد Update با خطای PK یا همون Primery Key مواجه میشم
حال اگه بخوام تو این Grid شماره ID رو خودش بصورت اتوماتیک بیاره بصورتی که ID واقعا آخرین شماره ID چکهای وارد شده باشه چیکار باید بکنم؟

hmm
سه شنبه 12 تیر 1386, 14:53 عصر
سلام
مجبور شدم این پست رو بیارم بالا تا شاید کسی بتونه کمکم کنه

SalarSoft
سه شنبه 12 تیر 1386, 19:35 عصر
توضیحات کمی مبهمه ولی نتیجه ای که من گرفتم اینه»

حال اگه بخوام تو این Grid شماره ID رو خودش بصورت اتوماتیک بیاره بصورتی که ID واقعا آخرین شماره ID چکهای وارد شده باشه چیکار باید بکنم؟
چرا نوع فبلد رو Identity تعیین نمی کنید؟
در این حالت دیگر نیازی نیست که مقداری رو برای chq_id درج کنید و اون به طور خودکار آخرین شماره درج خواهد شد.

ولی اگر می خوای که مقدار chq_id رو کاربر بتونه وارد کنه خب باید قبل از درج به عنوان یک بررسی قبل از بررسی primary key توسط sql ، خودت تکراری نبودن رو بررسی کنی، تا با پیغام خطلای primary key مواجه نشی.

ghafoori
سه شنبه 12 تیر 1386, 20:57 عصر
خب دوست عزیز ابتدا با متد compute در دیتا تیبل بزرگترین شماره Id را بدست بیاور سپس یکی به ان اضافه کن و ان را برابر شماره چک جدید قرار بده

Mrs.Net
سه شنبه 12 تیر 1386, 21:36 عصر
خب دوست عزیز ابتدا با متد compute در دیتا تیبل بزرگترین شماره Id را بدست بیاور
این چیه؟ کجاست؟

ghafoori
سه شنبه 12 تیر 1386, 22:29 عصر
متد Compute کارش انجام محاسبات روی فیلدها است مثلا برای شمارش جمع میانگین و غیره تا لازم نباشد برای این کارها مستقیما از بانک اطلاعاتی استفاده کنیم مثلا برای بزرگترین مقدار کد زیر بکار می رود

dt.Compute("max(id)","")
این کد بزرگ ترین مقدار فیلد id را بر می گرداند

Mrs.Net
سه شنبه 12 تیر 1386, 23:13 عصر
درصورتی که dt قبلا پر شده باشه؟

honey_sr
سه شنبه 12 تیر 1386, 23:38 عصر
اگه با sp عمل insert رو انجام میدی می تونی از این کد استفاده کنی .


SELECT id = IsNull(MAX(primaryKey),0)+1 from table_name
INSERT INTO(primaryKey, field1,field2,...) VALUES(id,@field1,@field2,...)

hmm
چهارشنبه 13 تیر 1386, 09:01 صبح
دوستان از جواباتون متشکرم
ولی انگار اشتباه توضیح دادم


خب دوست عزیز ابتدا با متد compute در دیتا تیبل بزرگترین شماره Id را بدست بیاور سپس یکی به ان اضافه کن و ان را برابر شماره چک جدید قرار بده
دیتا تیبلی که فیلتر شده چگونه آخرین id بانک رو میتونه محاسبه کنه


چرا نوع فبلد رو Identity تعیین نمی کنید؟
ببینید فیلد من identity هست 1000 تا چک از id یک تا هزار داخل بانک وجود داره
این grid کارش اینه که هر بانکی که کاربر انتخاب میکنه کلیه چکهای اون بانک رو نشون میده خب فرض کنیم کاربر بانک سپه رو انتخاب کرد
grid تمام اطلاعات چکهای بانکهای سپه رو میاره (تا اینجا هیچ مشکلی نیست) ولی آخرین شماره id چیه؟ مثلا 998 . (فرضا شماره id=1000 مربوط به بانک ملی است که تو این grid نیست) خب حالا اگه رکوردی بخواهد اضافه شود خود grid آخرین id رو یکی بهش اضافه میکنه و تو رکورد بعدی میزاره یعنی id=999 و این موجب خطای pk میشه
امیدوارم تونسته باشم مشکل رو بگم.

Alireza_Salehi
چهارشنبه 13 تیر 1386, 09:34 صبح
دوستان از جواباتون متشکرم
ولی انگار اشتباه توضیح دادم


دیتا تیبلی که فیلتر شده چگونه آخرین id بانک رو میتونه محاسبه کنه


ببینید فیلد من identity هست 1000 تا چک از id یک تا هزار داخل بانک وجود داره
این grid کارش اینه که هر بانکی که کاربر انتخاب میکنه کلیه چکهای اون بانک رو نشون میده خب فرض کنیم کاربر بانک سپه رو انتخاب کرد
grid تمام اطلاعات چکهای بانکهای سپه رو میاره (تا اینجا هیچ مشکلی نیست) ولی آخرین شماره id چیه؟ مثلا 998 . (فرضا شماره id=1000 مربوط به بانک ملی است که تو این grid نیست) خب حالا اگه رکوردی بخواهد اضافه شود خود grid آخرین id رو یکی بهش اضافه میکنه و تو رکورد بعدی میزاره یعنی id=999 و این موجب خطای pk میشه
امیدوارم تونسته باشم مشکل رو بگم.

1. معمولا فیلدی که برای کاربر مفهوم نداشته باشه اصلا به کاربر نشون نمیدن ( در اینجا فیلد chq_id) که بعدا مقادیر غیر مجازش باعث خطا بشه!

2. برای انجام عملیات (ویرایش ، حذف ، افزودن رکورد جدید) سعی کنید از فرم های جداگانه استفاده کنید و از گرید استفاده نکنید چون کاربر بهتر میفهمه چی کار داره میکنه.

3. در صورتی که فیلد از نوع Identity باشه اصلا نیازی نیست شما بدونید آخریش چی بوده و اصلا نیاز نیست در دستور Insert اون فیلد رو ذکر کنید !

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

hmm
چهارشنبه 13 تیر 1386, 13:22 عصر
معمولا فیلدی که برای کاربر مفهوم نداشته باشه اصلا به کاربر نشون نمیدن ( در اینجا فیلد chq_id) که بعدا مقادیر غیر مجازش باعث خطا بشه!

نشون داده بشه یا نه موجب خطا خواهد شد.

در صورتی که فیلد از نوع Identity باشه اصلا نیازی نیست شما بدونید آخریش چی بوده و اصلا نیاز نیست در دستور Insert اون فیلد رو ذکر کنید !

دستور insert ای در کار نیست در داخل grid اضافه میشه و با دستور update دیتا تیبل بروز میشه


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

این یک مثال بود . نه واقعیت

ممنون از وقتی که گذاشتی

hdv212
شنبه 16 تیر 1386, 00:54 صبح
hmm جان، به نظر من شما یه جدول دیگه بساز که آخرین شماره ی ID مربوط به چک رو در اونجا وارد کنه و نگه داره، زمان وارد کردن چک جدید، چه اطلاعات فیلتر شده باشه یا نه، با تابع Max بالاترین مقدار اون جدول رو بخون، و برای ثبت ID چک جدید، یکی به اون فیلد اضافه کن و به دو تا جدول insert کن، فکر کنم مشکلت حل بشه.

hmm
شنبه 16 تیر 1386, 12:58 عصر
ممنونم ولی میخوام اینکار یه جورایی به عهده خود grid باشه
بعیده همچین توانایی رو نداشته باشه

hdv212
یک شنبه 17 تیر 1386, 09:28 صبح
در مورد @@identity، در Sql server 2005 books online جستجو کن.

hmm
یک شنبه 17 تیر 1386, 10:30 صبح
ربطش به موضوع رو نمیدونم اگه ممکنه یه کدی که بتونه مشکل منو حل کنه بفرستین.

hdv212
یک شنبه 17 تیر 1386, 22:30 عصر
میخوام اینکار یه جورایی به عهده خود grid باشه

hmm عزیز وقتی توی select ای که کردی، بعضی از رکوردها ممکنه موجود نباشند، دیگه از دست Gridview کار برنمیاد، @@identity هم در sql server، آیدی آخرین فیلدی که وارد شده رو بر میگردونه، ولی این روش فقط برای همون لحظه است، دفعه بعد ممکنه مقدار null برگردونه یعنی هیچ رکوردی اون موقع insert نشده، بهترین راه همون جدولی هست که آخرین id وارد شده رو در خودش ذخیره کنه.

hmm
دوشنبه 18 تیر 1386, 07:59 صبح
من select ای بصورت دستی انجام ندادم
دیتاستی ساختم که با یک پارامتر که همان نوع بانک باشه در لحظه ورود به فرم پر میشه

hdv212
دوشنبه 18 تیر 1386, 09:54 صبح
من select ای بصورت دستی انجام ندادم

منظورم select دستی شما نیست، منظور من اطلاعات جدول شماست که در اثر Select ممکنه فیلتر شده باشن، حالا چه دستی و یا چه غیر دستی، به هر حال اگه فیلتر شده باشن یعنی ممکنه رکورد آخر در مجموعه نتایج برگردانده شده نباشه.

hdv212
دوشنبه 18 تیر 1386, 10:24 صبح
hmm جان یه فکر دیگه ای هم که به نظرم رسید، اینکه شما موقع Insert کردن میتونی یه Select از id ها بگیری و بزرگترین id رو برگردونی و یکی بهش اضافه کنی، اینطوری دیگه هم id هات پشت سر هم insert میشن و هم id تکراری وارد نمیکنی، اینطوری :
declare @NCode int
Set @NCode = (Select Max(bookID) from dbo.tbl_Books)
Set @NCode = isnull(@NCode,0) + 1
البته این به زبون sql هست، اگه بتونی برای اعمال insert,update,delete از sp استفاده کنی که خیلی بهتره، من هم همین کار رو میکنم.

hmm
دوشنبه 18 تیر 1386, 14:27 عصر
hdv212 (http://barnamenevis.org/forum/member.php?u=14084) عزیز
با بدست آورن max مشکلی ندارم سوال اینه چطوری میتونم این مقدار max رو در این ستون grid و در ردیف آخر قرار بدم

hdv212
دوشنبه 18 تیر 1386, 14:53 عصر
خب اگه آیدی رکورد جدیدی که داری وارد میکنی از آیدی رکورد قبلی بزرگتر باشه، به صورت اتوماتیک در آخر قرار میگیره، چون id به صورت pk هست و در دیتابیس روی اون index خورده، لذا خود دیتابیس index ها رو از کوچک به بزرگ، Sort میکنه ، مگر اینکه در select سورت به صورت desc تنظیم شده باشه.

hmm
سه شنبه 19 تیر 1386, 17:01 عصر
با بدست آورن max مشکلی ندارم سوال اینه چطوری میتونم این مقدار max رو در این ستون grid و در ردیف آخر قرار بدم

ممنونم ولی جوابتون ارتباطی به سئوال من نداره

SalarSoft
سه شنبه 19 تیر 1386, 20:56 عصر
کار شما در کل چند تا ایراد داره:
1- به نظر میاد که بیش از حد به DataAdapter و DataGrid اعتماد و اعتقاد دارید. (این یعنی مار در آستین پروراندن)

2- در حقیقت مشکل شما با DataTable و مقادیر آن است و نه با DataGrid چون گرید نقش یک نمایشگر رو انجام میده و کار اصلی در پشت پرده و با DataTable است.


3- اگر فیلد شما identity است و اگر از DataAdapter استفاده می کنید و اگر DataAdapter رو به صورت دستی تغییر نداده باشد و درست configure شده باشد، به هیچ وجه پیغام خطایی مبنی بر تکراری بودن فیلد نخواهد داد. چون اصولا هیچ دستوری در قسمت InsertCommand مربوط به DataAdapter برای این فیلد ایجاد نشده است!

4- مار را بکشید و از StoredProcedure استفاده کنید