PDA

View Full Version : گفتگو: بهترین روش برای افزودن به بانک (تحت شبکه)



bmanfy
جمعه 11 بهمن 1387, 11:09 صبح
سلام دوستان من چند وقتیه سردرگم شدم و مودنم بهترین روشها وبا صرفه ترین اونها برای کار با بانک اطلاعاتی اون هم تحت شبکه چیه .

راستش میخوام برنامه ای رو بنویسم که خیلی بزرگه و میخوم قبل از شروع به نوشتن معقول ترین روشها رو انتخاب کنم.

میخوام اطلاعاتی رو در بانک ذخیره کنم (از Sql Server 2005 استفاده می کنم ) . حالا به نظر شما برای افزودن به بانک از چه روشی استفاده کنم . و هم چنین برای اصلاح کردن یک رکورد ...
از StoeProc یا از کد Sql به صورت آنی در حال اجرا و یا از همون امکانات insert و post مربوط به ado .
با اجازتون چنتا طرج رو خودم میگم بگید کدوم بهتره یا اگه روش بهتر داشتید بگید .
ممنون.

bmanfy
جمعه 11 بهمن 1387, 11:17 صبح
اولین روش (البته دقت بکنبد که قرار تو شبکه کار بشه)
استفاده از همون Append و Post با این شکل که قبل از ارسال تکراری بودن درون اون AdoQuery که واکشی شده چک بشه . و کلیه خطاهایی که ممکنه به دلیل عدم درست بودن اطلاعات ایجاد بشه هم بررسی بشه و سپس با استفاده از یک Try اطلاعات رو اظافه کنیم که اگر اضافه نشد نتیجه بر این بگیریم که توسط کاربر دیگری چنین کدی ثبت شده .


Try
adoQuery1.append ;
.
.
.
adoQuery1.Post ;
Except
Showmessage('توسط کاربر دیگری ثبت شده') ;
end;

که خوب برای اطلاح هم میشه از همین روش استفاده کرد و اگر کاربر دیگری رکورد رو قبل از ارسال اطلاعات ما تغییر داده باشه قسمت Except اجر میشه . برای بررسی کلید تکراری هم با یک Locate

البته منظور من منطق اصلیه کاره و مناسب بودنش برای کار .

bmanfy
جمعه 11 بهمن 1387, 11:23 صبح
یکی هم اینکه دقیقا مثل کد بالا باشه اما با دستورات Sql باشه . که برای Adoquey مینویسیم . حالا مثلا به صورت یک تابع پارامتر دار باشه .


Insert into Tbl Values ( : Value)

که البته جستجو در اطلاعات سمت کاربر برای عدم تکراری بودن انجام بشه و اگه یه وقتی تو بانک اصلی تکرار شده باشه Except اجرا میشه .

bmanfy
جمعه 11 بهمن 1387, 11:26 صبح
البته این دوتا روش بالا زیاد برای خودم هم دلچسب نیست .
به نظر شما ایا اینکه سعی بشه تو بانک ذخیره بشه و نشد بره به Except هزینه بر نیست؟
چه طور میشه از AdoQuery یه مقدار برگشتی گرفت . مثلا مثل کد خطا . یا هرچیزی .که اینجوری بشه اطلاعات رو دقیق درون بانک بررسی کرد و اگه تکراری باشه یه کد خطا برگردونیم ؟

البته تو این جالت و StorProc یه مسئله ای نظر منو جلب کرده که در پایان میگم .

bmanfy
جمعه 11 بهمن 1387, 11:35 صبح
روش بعدی که این به نظر جالتره اما یه مسئله داره استفاده از Store Proc ها است که یه پروسجر به شکل زیر بنویسم :


Crete Procedure Tadd (@pid int , @pname nvarchar(20))
as
insert into Tbl Value(@pid , @pname)


البته میشه به شکل زیر هم نوشتش که قبلش تکراری بودن رو بررسی کنه :



.
.
as
if Exsists(select id From Tbl Where id = @pid)
یک کد خطا برگردونیم
else
insert into .......

البته اینجا دیگه نمیدونم چه طوری باید این خطا رو توسط برنامه دریافت کنم ؟

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

bmanfy
جمعه 11 بهمن 1387, 11:44 صبح
همه اینها رو گفتم البته خیلی شکسته و .... و منظورم روش کلی بود .
حالا با توجه به مطالبی که گفتم امیدوام دوستان متوجه شده باشند که حرف من سر چه چیزیه .
من میخوام بهترین روش و سریعترین روشها رو یاد بگیرم .
ممنون
به هر حال اگر یکی از دوستان یک روش رو با مثال بگه ممنون میشم البته هم برای افزودن و هم برای اصلاح .
ممنون .

vcldeveloper
جمعه 11 بهمن 1387, 12:04 عصر
من میخوام بهترین روش و سریعترین روشها رو یاد بگیرم .
بهترین روش وجود نداره؛ بهترین روش، روشی هست که بهترین جواب را برای پروژه شما بده، و شاید این بهترین جواب برای یک پروژه دیگه بدترین جواب باشه!


فرض کنیم کاربر میخواد فردی با کد 12 رو تغییر بده .

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


به نظر شما ایا اینکه سعی بشه تو بانک ذخیره بشه و نشد بره به Except هزینه بر نیست؟
هست. استفاده از Exception به عنوان یک مسیر کنترلی در برنامه کار اشتباهی هست. Exception باید فقط برای Exception استفاده بشه.


چه طور میشه از AdoQuery یه مقدار برگشتی گرفت
با تعریف پارامتر از نوع Out برای SP.

خواهشا برای کل پروژه تان یک تاپیک درست نکنید، و برای هر سوال یک تاپیک درست کنید. این تاپیک شما خودش شامل چندین سوال هست، که هر کدامشان می توانند منجر به چند صفحه بحث بشوند!

bmanfy
جمعه 11 بهمن 1387, 18:44 عصر
خیلی ممنون آقای کشاورز .
من برای کل پروژه ام که تاپیک باز نکردم فثط تاپیکی باز کردم برای چگونه افزودن .



با استفاده از خصوصیت LockType

طبق اون چیزی که من گفتم اون تغییرات از مانی ممکنه رخ بده که کاربر دکمه ی Edit رو میزنه تا زمانی که دکمه ثبت رو میزنه .
و زمانی که دکمه ی Edit رو میزنه ما عملا جدول رو Edit نمیکنم . در واقع زمانی Edit رو انجام میدیم که دکمه ی ثبت رو میزنه .
و از زمانی که دکمه Edit رو میزنه و زمانی که واقعا اطلاعات رو ثبت میکنه میشه گفت یه مدت زمان زیادی رخ صرف میشه . و برای اینکه اون اتاقی که من گفتم نیفته باید زمانی که دکمه ی Edit رو میزنه رکورد کورد نظر رو قفل کنیم . که منجر میش اگه کاربران دیگه به اون نیازی داشته باشن نتونند از اون رکورد استفاده کنند . (به نظر شما معقوله که چنین کارب تنجام بشه )

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

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



با تعریف پارامتر از نوع Out برای SP.

لازمه اون پارامتر رو هم توی تابع تعریف بشه ؟ یا فقط توی شی Sp کفایت میکنه .
وقته یه Sp رو به تابع وصل میکنیم تو پارامترهای اون یکی با نام Return_Value هست اما چه طور میشه از اون استفاده کرد ؟

کسی مقاله ای چیزی سراغ نداره یا کتاب که در باره Ado کامل گفته باشه . اخه کتابها همش از BDE گفتن .

vcldeveloper
جمعه 11 بهمن 1387, 21:07 عصر
کسی مقاله ای چیزی سراغ نداره یا کتاب که در باره Ado کامل گفته باشه . اخه کتابها همش از BDE گفتن .
سوال های شما در این تاپیک بیشتر مربوط به SQL Server میشه تا به ADO یا BDE.


از طرف دیگه اگر یک رکورد رو قفل کنیم و سیستم اون کاربر به هر دلیل خاموش بشه یا خراب بشه و ادامه ی کار باز بمونه چه اتاقی میافته ؟
بستگی به موتور بانک اطلاعاتی داره که با طولانی شدن قفل چه واکنشی انجام میده. یک حالت هم این هست که برنامه بصورت multi-tier نوشته بشه، و عملا کاربران ارتباط مستقیمی با بانک نداشته باشند، و کل این امور را لایه میانی بر عهده بگیره.


و از زمانی که دکمه Edit رو میزنه و زمانی که واقعا اطلاعات رو ثبت میکنه میشه گفت یه مدت زمان زیادی رخ صرف میشه . و برای اینکه اون اتاقی که من گفتم نیفته باید زمانی که دکمه ی Edit رو میزنه رکورد کورد نظر رو قفل کنیم . که منجر میش اگه کاربران دیگه به اون نیازی داشته باشن نتونند از اون رکورد استفاده کنند . (به نظر شما معقوله که چنین کارب تنجام بشه )
لازم نیست رکورد قفل بشه، میشه با استفاده از حالت Optimistic فقط زمانی که یکی از فیلدهای کلید توسط کاربر تغییر داده شدند، پیام خطا صادر کرد، یا در صورت استفاده از Multi-tier، و ClientDataset، حتی فیلدهایی که تداخل دارند را به کاربر نمایش داد، تا خودش تصمیم بگیره.
برای فیلدهایی که شماره گزاری میشند، و باید شماره شان منحصر به فرد باشه، بهتر هست که شماره گزاری در سمت سرور انجام بشه، یعنی یا فیلد Auto Number باشه، یا یک تابع یا SP در سطح سرور برای دریافت آن فراخوانی بشه، تا کلاینت ها هیچ وقت شماره یکسان دریافت نکنند.

bmanfy
شنبه 12 بهمن 1387, 09:26 صبح
لازم نیست رکورد قفل بشه، میشه با استفاده از حالت Optimistic فقط زمانی که یکی از فیلدهای کلید توسط کاربر تغییر داده شدند، پیام خطا صادر کرد، یا در صورت استفاده از Multi-tier، و ClientDataset، حتی فیلدهایی که تداخل دارند را به کاربر نمایش داد، تا خودش تصمیم بگیره.

طبق اون چیزی که من گفتم این هم عملی نیست اخه تغییرداده نمیشه .
اولی یک رکورد با کد 10 رو میخواد اصلاح بکنه
دومی میاد همین 10 رو حذف میکنه .
سومی یک رکورد جدید با کد 10 میسازه .
اولی اطلاعات جدید رو ثبت میکنه .
درواقع اینجا اطلاعات سومی خراب میشه بدون اینکه کسیمتوجه بشه . و اگر دقت بکنبد هیچ کدی تغییرنکرد .



برای فیلدهایی که شماره گزاری میشند، و باید شماره شان منحصر به فرد باشه، بهتر هست که شماره گزاری در سمت سرور انجام بشه، یعنی یا فیلد Auto Number باشه، یا یک تابع یا SP در سطح سرور برای دریافت آن فراخوانی بشه، تا کلاینت ها هیچ وقت شماره یکسان دریافت نکنند

همیشه که فیلد کلید نمیشه Auto باشه !

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

vcldeveloper
شنبه 12 بهمن 1387, 18:09 عصر
اولی یک رکورد با کد 10 رو میخواد اصلاح بکنه
دومی میاد همین 10 رو حذف میکنه .
سومی یک رکورد جدید با کد 10 میسازه .
همچین چیزی اتفاق نمیافته. فیلدهای ID باید مقدار Unique بسازند که تکرار نشه. اگر رکوردی IDاش 10 بوده و حذف شده، دیگه نباید از اون شماره استفاده بشه. برای همین گفتم شماره گزاری یا اختصاص شماره به فیلد ID باید در سمت سرور صورت بگیره. در این حالت، اولی رکورد 10 را اصلاح میکنه، اگر قبل از ثبت اصلاحش رکورد 10 توسط دومی حذف بشه، اولی خطا میگیره که همچین رکوردی وجود نداره. اگر اصلاحش ثبت بشه، و بعد دومی حذف کنه، مشکلی بوجود نمیاد. سومی هم هر وقت خواست، میتونه رکورد جدید درست کنه، و مطمئن باشه که ID تکراری دریافت نمیکنه.

bmanfy
یک شنبه 13 بهمن 1387, 10:09 صبح
همچین چیزی اتفاق نمیافته. فیلدهای ID باید مقدار Unique بسازند که تکرار نشه . اگر رکوردی IDاش 10 بوده و حذف شده، دیگه نباید از اون شماره استفاده بشه.

ابنجوری که نشد . فرض بکنید این فیلد کلید مربوط به شماره پرونده یک کاربر باشه یا اصلا کد ملی . وقتی حذف بکنیم و بخواهیم دوباره اضافه بکنیم که نمیشه کد ملی فرد رو تغییر بدهیم .
و از طرفی تمام فیلدهای کلیدی رو که نمیشه گذاشت در طرف Server تعریف بشه .
مثلا فرض میگیریم یک فاکتور فروش با شماره 10 .
اولی فاکتور 10 رو میخواد اصلاح بکنه .
دومی اشتباها و ناخواسته این فاکتور رو حذف میکنه .
حالا میخواد دوباره این فاکتور رو اضافه کنه . (فاکتوری که دست مشتری هست رو که نمیشه شماره جدیدی بهش داد)

bmanfy
یک شنبه 13 بهمن 1387, 10:24 صبح
البته الان یه چیزی به ذهنم رسید اینکه اگر اطلاعات در سمت خود کاربر اضافه بشه دیگه با این مشکل مواجه نمیشه .
یعنی در واقع با استفاده از همون Ado یی که در سمت کاربر قرار داره و اطلاعات درون اون واکشی شده .
با استفاده از append و Post که خوب :
پس اگر توسط دیگری حذف شده باشه و توسط دیگری اظافه شده باشه باز هم به کاربر اولی این تغییر اطلاع داده میشه .
من قبلا خودم این چنین تست کرده بودم که :
اولی میخواد کد 10 رو تغییر بده
دومی زودتر میاد و به 12 تغیی میده .
دومی دوباره به 10 تغییر میده
حالا اولی میخواد اون رو ثبت کنه با این که مقدار دوباره به حالت اول برگشته باز هم خطا بهش داده میشه .
البته من این رو تو برنامه نویسی با استفاده از sucket Connection و در شی ClientDataSet انجام داده بودم .
امیدوارم برای Ado ها هم همینجور باشه . که به احتمال زیاد هم همینجوره .

accpascal
یک شنبه 13 بهمن 1387, 18:31 عصر
تعداد کاربرانی که از پروژه شما استفاده می کنند نقش مهمی در برنامه نویسی شما دارند
هرچه تعداد کاربران بیشتر باشند امکان همزمانی ثبت رکوردها بیشتر است بنابراین ابتدا تعداد حدودی کاربرانت را مشخص کن

bmanfy
سه شنبه 15 بهمن 1387, 17:55 عصر
تعداد کاربرانی که از پروژه شما استفاده می کنند نقش مهمی در برنامه نویسی شما دارند

تعداد زیادی کاربر از برنامه استفاده میکنند . نگرانی من هم به همین خاطره .

bmanfy
سه شنبه 15 بهمن 1387, 18:08 عصر
البته با بهره گیری از راهنمایی های جناب کشاورز یه چیز دیگه هم به ذهنم رسید :
میتونیم برای جدول دوتا فیلد کلیدی در نظر بگیریم . مثلا یکی کد ملی و دیگری یه فیلد عددی خودکار Uique باشه مثلا با نام Id
که کاربر از فیلد دوم با خبر باشه . و زمانی که مل میخواهیم اطلاعات رو اصلاح کنید بر اساس فیلد id کار کنیم .
که این چنین میشه .
اولی میخواد فیلد id 10 و کد ملی 123 رو اصلاح کنه .
دومی میاد اون رو پاک میکنه .
سومی یه سطر جدید با کد ملی 123 مسازه .
اما فیلد id که ساخته میشه دیگه کدش 10 نیست .
پس زمانی که میخواد اولی اطلاعات رو بفرسته .....

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

bmanfy
سه شنبه 15 بهمن 1387, 18:24 عصر
یه مسئله ای که همیشه فکر من رو به خودش جلب میکنه اینه که آیا روشهایی که استفاده میکنم درسته یا نه . منظورم از نظر هزینه ی اونهاست . یعنی اینکه آیا روش بهتر و ساده تری هم برای این کار هست یا خیر .
مهمترین مسئله ای که همیشه باعث نگرانی من میشه چک کردن فیلد کلیدی برای اینکه اگر بخواد کاربر یه رکورد تکراری به بانک اضافه کنه بتونم خطایی رو بهش نشون بدم .
تا حالا همیشه از روشهای دستی برای این کار استافده میکردم . و خودم توی بانک جستجو میکردم و .....
به نظر شما اگر برای چک کردن بسپارم به عهده ی خود Sql سرور کار اشتباهیه .
یعنی من اطلاعاتم رو به Sql بفرستم و بعد از ارسال @@Error رو بررسی کنم . و با توجه به خطایی که از طرف Sql برگردونده میشه خطای مناسب رو نمایش بدم .
(البته قبل از ارسال صحت اطلاعات رو مثلا نوع و .... رو خودم چک بنم )
این روش چه طوره ؟
شما از چه روشی استفاده میکنید ؟

accpascal
سه شنبه 15 بهمن 1387, 23:29 عصر
من پروژه ای در حال استفاده دارم که در هر شرکتی از 10 تا 60 نفر از آن استفاده می کنند پروژه بصورت دولایه بوده و کلاینتها مستقیما اطلاعات را از سرور دریافت و ویرایش وثبت می نمایند
در هرجای پروژه که نیاز به اضافه یا اصلاح رکوردها می باشد من همیشه قبل از نهایی کردن رکورد جستجو ها را انجام می دهم و تا حالا به مشکلی برنخورده ام
ضمنا علاوه بر جستجوی قبل از ویرایش دستور نهایی را در رویداد try ... except ... end قرار می دهم
تا در فاصله عمل جستجو و ثبت رکورد جدید اگر خطای تکرار رکورد بوجودآمد پیگیری شود
در هر صورت همیشه امکان ثبت اطلاعات تکراری و یا اصلاحات همزمان وجود دارد که مهم نحوه مدیریت آنها می باشد

E_Alikhani
چهارشنبه 16 بهمن 1387, 09:51 صبح
در هرجای پروژه که نیاز به اضافه یا اصلاح رکوردها می باشد من همیشه قبل از نهایی کردن رکورد جستجو ها را انجام می دهم و تا حالا به مشکلی برنخورده ام
ضمنا علاوه بر جستجوی قبل از ویرایش دستور نهایی را در رویداد try ... except ... end قرار می دهم
تا در فاصله عمل جستجو و ثبت رکورد جدید اگر خطای تکرار رکورد بوجودآمد پیگیری شود
در هر صورت همیشه امکان ثبت اطلاعات تکراری و یا اصلاحات همزمان وجود دارد که مهم نحوه مدیریت آنها می باشد

اگريكي ركورد 10 رانامشو را به رضا و تاريخ ... تغيير بده
ويكي ديگه هم همين ركورد 10 رو نامشو به علي تغيير بده(تاريخ رو تغيير نميده) چه اتفاقي مي افته
تاريخ چي ميشه

bmanfy
چهارشنبه 16 بهمن 1387, 10:06 صبح
اگريكي ركورد 10 رانامشو را به رضا و تاريخ ... تغيير بده
ويكي ديگه هم همين ركورد 10 رو نامشو به علي تغيير بده(تاريخ رو تغيير نميده) چه اتفاقي مي افته
تاريخ چي ميشه


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

bmanfy
چهارشنبه 16 بهمن 1387, 10:25 صبح
اگر اطلاعات رو به یک Sp در Sql ارسال کنیم و یا با استفاده از یک Query در برنامه دستورات insert رو بنویسیم افزودن اطلاعات هر دو در سمت سرور خواهد بود .
آیا این دو روش از نظر صرف هزینه ی زمانی یکسانند ؟ کدوم به صرفه تر ا ست ؟

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

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

vcldeveloper
چهارشنبه 16 بهمن 1387, 17:05 عصر
اولی نام رکورد را از نام رضا به علی تغییر میدهد .(نام فیلد کلیدی نیست)
دومی هم در سمت خودش رضا رو میبینه در حالی که به علی تغییر کرده .
(آیا اگر دومی برای این رکورد مقداری بفرسته با وجود اینکه تغییر کرده خطایی داده نمیشه ؟ که فکر میکنم داده نشه .)
بستگی به تنظیمات برنامه شما داره. به سه حالت میشه این کار را تنظیم کرد:
1- وقتی رکوردی تغییر کرد، برنامه برای ایجاد دستور Update فقط به دنبال فیلدهای کلیدی بگرده. خب اگر تغییر مربوطه روی فیلد کلید اعمال نشده باشه، تغییر ثبت میشه، و گرنه خطا دریافت میشه.

2- برای ایجاد دستور Update از تمام فیلدهای رکورد استفاده بشه؛ در اون صورت هر فیلدی که تغییر کرده باشه، حتی اگر فیلد کلید نباشه، خطا دریافت میشه.

3- برای ایجاد دستور Update از فیلدهای کلید و فیلدی که تغییر کرده استفاده بشه؛ در اون صورت فقط در صورتی که فیلد کلید یا فیلدی که تغییر کرده توسط کاربر دیگه ایی تغییر داده شده باشه، خطا دریافت میشه، و اگر فیلدی غیر کلیدی که توسط کاربر فعلی هم ویرایش نشده، توسط یک کاربر دیگه تغییر کنه، تغییرات با موفقیت ثبت میشه.

bmanfy
پنج شنبه 17 بهمن 1387, 09:56 صبح
بستگی به تنظیمات برنامه شما داره. به سه حالت میشه این کار را تنظیم کرد:
1- وقتی رکوردی تغییر کرد، برنامه برای ایجاد دستور Update فقط به دنبال فیلدهای کلیدی بگرده. خب اگر تغییر مربوطه روی فیلد کلید اعمال نشده باشه، تغییر ثبت میشه، و گرنه خطا دریافت میشه.

2- برای ایجاد دستور Update از تمام فیلدهای رکورد استفاده بشه؛ در اون صورت هر فیلدی که تغییر کرده باشه، حتی اگر فیلد کلید نباشه، خطا دریافت میشه.

3- برای ایجاد دستور Update از فیلدهای کلید و فیلدی که تغییر کرده استفاده بشه؛ در اون صورت فقط در صورتی که فیلد کلید یا فیلدی که تغییر کرده توسط کاربر دیگه ایی تغییر داده شده باشه، خطا دریافت میشه، و اگر فیلدی غیر کلیدی که توسط کاربر فعلی هم ویرایش نشده، توسط یک کاربر دیگه تغییر کنه، تغییرات با موفقیت ثبت میشه.


ضمن تشکر .
خوب معمولی ترین روش همون روش اول هست که بر اساس فیلد کلیدی برای مشخص کردن Update استفاده میشه که دقیقا زمانی که من سوال رو مطرح کردم همین روش تو ذهنم بود . پس نتیجه ای که میشه گرفت اینه که یاید از روش 2 و 3 استفاده کنیم .

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

خوب این روشی بود که در این لحظه به ذهن من رسید .
روش ساده تر و کم هزینه تری سراغ دارید ؟
به نظر شما اینکه برای هر تغییر یک پیوند زده بشه هزینه بر نیست ؟
آیا این مسئله اصلا ارزش پیاده سازی رو داره یا به درد سرهاش نمی ارزه ؟

میدونید که Ado خودش این چیزا رو بررسی میکنه . یعنی اگه در طرف کاربر و با استفاده از Append و Post این کارها رو انجام بدیم دیگه نیاز به بررسی نیست (البته اینجا دیگه ناچاریم از Try ..... Except ...... end ) استفاده کنیم که یه گفته ی آقای کشاورز این کار درستی نیست . (البته در پست بعدی در این باره کمی حرف دارم ) اما دیگه اون وقن درد سر بررسی و .... رو نداریم .

(اونقدرا هم که میگن برنامه نویسی شبکه راحته راحت نیست که ، یه عالمه دردسر داره)

bmanfy
پنج شنبه 17 بهمن 1387, 10:08 صبح
حرف من در ورد استفاده از Try برای بررسی خطاها در Ado:
البته ممکنه حرفهای من ناشی از این باشه که در این مورد اطلاعات کاملی نداشته باشم .
اصلا چه طور میشه که به Except میره ؟ خوب زمانی که یک خطا رخ میده . چه طور میفهمه که خطا رخ داده ؟ خوب ببرسی میکنه .
خوب عقیده ی من اینه که زمانی کهم توسط کاربر بررسی بشه توسط کامپایلر هم بررسی میشه و بررسی ما باعث میشه عملیات کمی به تعویق بیافته و حالات هر چند ممکنه کم باشه اما یه زمان اضافه .
خوب اگر ما به راحتی توسط Try , Except این کار رو انجام بدیم و توجه به مقدار خطای بازگشتی (البته نمیدونم کد خطا رو چه طور به دست میارن . البته جتما میشه . تو چه متغییری کد خطا ذخیره میشه ؟) یه خطای مناسب بدیم چه اتفاقی میخواد بیافته . مگه چه زیانهایی برای برنامه داره .
البته یه چیزی که هست گمان میکنم (حالا در مورد Ado ) بررسی توسط مدیریت پایگاه داده انجام میشه نه Ado. چرا که اگر دقت کنید زمانی که یک رکورد با کد تکراری ذخیره کنیم ساید اطلاعات رو توی DbGrig میبینیم که به جدول اضافه کرده و زمانی که میخواسته کلید رو اضافه کنه مدیر پایگاه گفته برو بابا . البته با استفاده از متد Cancel ...... ادامه کار رو در درست گرفت .


حالا از Try بگذریم .

استفاده از کدهای خطا دورن Sql چی این رو هم رد میکنید ؟
به هر حال تون هم خودش چک میکنه و ما هم که اگه بخوایم چک بکنیم به نظر بنده یه کار اضافیه ؟ کسی این حرف رو تایید میکنه ؟
ممنون از همگی .

vcldeveloper
پنج شنبه 17 بهمن 1387, 13:01 عصر
اون سه روشی که گفته شد را لازم نیست شما پیاده سازی بکنید، بلکه ADO اون کار را برای شما انجام میده، شما فقط حالت مورد نظرتان را انتخاب می کنید.


(البته اینجا دیگه ناچاریم از Try ..... Except ...... end ) استفاده کنیم که یه گفته ی آقای کشاورز این کار درستی نیست .

من نگفتم از Try...except استفاده نکنید! بلکه گفتم از آن به عنوان یک ساختار کنترلی برای برنامه استفاده نکنید. یعنی try...except برای کنترل استثناء هست، نه کنترل برنامه. بخش except باید فقط برای کنترل خطا استفاده بشه، نه به عنوان یکی از مسیرهای معمول کنترل برنامه.

bmanfy
جمعه 18 بهمن 1387, 08:54 صبح
ضمن تشکر .


اون سه روشی که گفته شد را لازم نیست شما پیاده سازی بکنید، بلکه ADO اون کار را برای شما انجام میده،

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


شما فقط حالت مورد نظرتان را انتخاب می کنید.

راستش من چنین انتخابی تا به حال به چشمم نخورده . میشه بگید کجاست ؟
البته برم خونه خودم هم دنبال میگردم اما حالا اگه میشه شما هم بگید که یه وقت اگه پیدا نکردم .

خوب حالا این که گفتید برای Ado مشخص کنیم . پس قاعدتا برای adoQuery هم میتونه اتخاب کنه . حالا سول من اینه که در محدوده ی Append و Post این بررسی رو انجام میده . منظورم اینه که اگه با دستوارت Sql در query عملیات مربوطه رو انجام بدیم باز هم چک میکنه یا نه ؟


بخش except باید فقط برای کنترل خطا استفاده بشه، نه به عنوان یکی از مسیرهای معمول کنترل برنامه.

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

vcldeveloper
جمعه 18 بهمن 1387, 23:02 عصر
راستش من چنین انتخابی تا به حال به چشمم نخورده . میشه بگید کجاست ؟
ADODataSet1.Properties
اینجا جزو خصوصیات دینامیک هستند، و از یک موتور بانک اطلاعاتی تا یک موتور بانک اطلاعاتی فرق می کنند. می تونید مثلا در راهنمای SQL Server درباره خصوصیات دینامیکش مطالعه کنید. چند نمونه سورس کد درباره خطای Row Cannot be located در سایت موجود هست که برای رفع آن از همین خصوصیات دینامیک استفاده شده. می تونید برای چگونگی استفاده از آنها، به اون تاپیک ها مراجعه کنید.


حالا اگه به عنوان یک مسیر کنترلی برای برنامه استافده کنیم چه اتفاقی میافته ؟
سربار برنامه را افزایش دادید، چون هربار برای حرکت کاربر در اون مسیر کنترلی باید یک Exception تولید کنید.

bmanfy
شنبه 19 بهمن 1387, 19:01 عصر
چطور میتونم مقدارError@@ را به برنامه برگردانم . یا کلا یک مقدار out در پارامترهای Query قرار بدم .
راستش هر کار کردم نتونستم انجامشی بدم .
میشه با یک مثال کوچک یکی از عزیزان این مسله رو برنام روشن بکنه ؟

bmanfy
دوشنبه 21 بهمن 1387, 08:56 صبح
سربار برنامه را افزایش دادید، چون هربار برای حرکت کاربر در اون مسیر کنترلی باید یک Exception تولید کنید

خوب حالا میگید Try هزینه بره . پس از Try میگذزیم .
آیا اگه در سمت سرور اطلاعات رو ثبت کنیم (بدون اینکه بررسی کنیم) و در انتها مقدار @@Error رو بررسی کنیم آیا آون وقت هم کار اشتباهیه ؟

bmanfy
دوشنبه 21 بهمن 1387, 08:58 صبح
با توجه به مسائلی که در مورد ثبت کردن در سمت کاربر بر میخوریم که منظورم همون به روز نبودن جداول هستش که در هر بار برای ثبت اطلاعات باید جستجو انجام بدیم در حالی که ممکنه در همون لحظه یک رکورد تکرار با اون مقداری که ما می خوایم وجود داشته باشه که حالا ممکنه به هر دلیلی در سمت کاربر واکشی نشد ه باشه .
البته با توجه به اینکه و تمام احترامی که برای Ado قائل هستم و اینکه خیلی کارهای کنترلی در زمان ثبت رو بررسی میکنه اما به نظرم یه مقداری غیر حرفه ای به نظر میرسه .
خوب حالا اگه بخوایم در سمت سرور این تغییرات رو ثبت کنیم . برای افزودن به مشکل خاصی بر نمیخوریم . اما برای اصلاح کردن چرا یه مقداری مشکل هست به خصوص اگر پای فیلد غیر کلید در میان باشه .
خوب برای این من دوتا روش به ذهنم رسید که میگم که اگر شما هم در موردش نظر بدین خیلی ممنون میشم .
1 . زمان اصلاح به جای اینکه مقدار فیلد کلید رو در قسمت Where بزاریم مقدار کل رکورد رو قرار بدیم . (همون طرح شما ره 2 که جناب کشاورز گفتند) که البته اینکه بخوایم تمام فیلدها رو بنویسیم خیلی سخته به خصوص اگر تعداد فیلدها زیاد باشه .
یه راه برای ساده شدن اینه که از پیوند زدن استفاده کنیم . حالا از پیوند بگذریم آیا امکان این هست که دوتا رکورد رو مستقیما با هم مقایسه کنیم . Rec1 = Rec2

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

vcldeveloper
دوشنبه 21 بهمن 1387, 17:27 عصر
خوب حالا میگید Try هزینه بره . پس از Try میگذزیم .
نه دیگه!! پست ها را با دقت بخونید. بین "Try هزینه بره" با "Exception هزینه بره" تفاوت زیادی وجود داره! تازه اون هم Exception ایی که به عنوان یک مسیر کنترلی برای برنامه تعریف بشه، نه Exception ایی که کارش واقعا همون کنترل خطاها ست! فردا نرید تام کدهای try..finally و try..except را حذف کنید، بگید فلانی گفته اینها هزینه برند!

bmanfy
سه شنبه 22 بهمن 1387, 18:40 عصر
نه دیگه!! پست ها را با دقت بخونید. بین "Try هزینه بره" با "Exception هزینه بره" تفاوت زیادی وجود داره! تازه اون هم Exception ایی که به عنوان یک مسیر کنترلی برای برنامه تعریف بشه، نه Exception ایی که کارش واقعا همون کنترل خطاها ست! فردا نرید تام کدهای try..finally و try..except را حذف کنید، بگید فلانی گفته اینها هزینه برند!


:لبخندساده::لبخند:
با عرض شرمندگی . ظاهرا از کلمات نامناسبی در بیان استفاده کردم . نه منظور من در همون زمینه ای بود که خودم در موردش گفتم . یعنی به عنوان یک مسیر کنترلی . نه چیز دیگری .
ممنون .

bmanfy
دوشنبه 05 اسفند 1387, 20:55 عصر
دوستان خوب . کاملا قاطی کردم .
والا راهها خیلی زیاده و هر کدوم یه مزیت و اشکال دارند . نمیدونم از چه راهی استفاده کنم .
میشه یک برنامه نویس با تجربه بیاد و آقایی بکنه و روند افزودن و اصلاح کردن به یک بانک اطلاعاتی رو بگه . اخه دنبال یک روش کاملا کم هزینه و مطمئن هستم .
اگر هم کسی حال توضیح و گفتن رو نداره . یه سورس کد کوچیک کارم رو راه میندازه که فقط ببینم .
خدایش خیلی وسواس دارم و برنامه ای هم که دارم خیلی بزرگ و حساسه . نمیخوام بی گدار به آب بزنم و در وسط کار سقوط آزاد داشته باشم .
ممنون

bmanfy
شنبه 15 فروردین 1388, 10:39 صبح
خوب بعد از این همه بحث آخرش از روش زیر استفاده کردم که حالا یکی دوتا سوال پیش اومده که در پست بعدی بیان میکنم :
روشی که استفاده کردم :
تمام اعمال را با استفاده از Sp انجام داده میشه . و یک فیلد از نوع Identity برای تمام جدولها قرار داده ام .
و برای هم جدول هم یک Trigger گذاشتم که به محض تغییر جدول تمام سطرهایی رو که تغییر کرده اند رو پاک میکنه و مثل همونها دوباره ایجاد میکنه با این تفاوت که عمل باعث میشه فیلد id (همون فیلد از نوع Identity ) تغییر کنه .
و کاربر وقتی میخواد روی یک سطر خاص تغییر اعمل کنه از این فیلد استفاده میکنه که اگر تغییر کرده باشه خوب حتما توسط دیگر ی تغییر کرده . و پیام مناسب نشون داده میشه .
آیا دوستانی که در زمینه برنامه نویسی دیتابیس تحت شبکه کار می کنند هم از چنین روشی استفاده میکنند ؟

bmanfy
شنبه 15 فروردین 1388, 10:46 صبح
خوب با این روش مشکل خاصی ندارم . و کامل برنامه ام رو نوشیتم . اما یه چیزی هست که یه کم ذهنم رو مشغول کرده . اونم اینه که داره این فیلد Identity تغییر میکنه . و خوب تا کجا پیش میره . آیا یه روزی اون بازه ی عددی اون تموم نمیشه . گیر نمیکنه ؟
اون وقت تکلیف چیه .

یه چیز دیگه . به دلیل اینکه داشتم این مدت برنامه رو هم تست میکردم این فیلد Identity ÷یش روی کرده . چه طور میتونم دوباهر شروع شدند رو به صفر برگردونم ؟

barat121
پنج شنبه 25 تیر 1388, 07:58 صبح
سلام
میتونی توی قسمت طراحی جدول اون فیلد رو ابتدا برگردونی به حالت معمولی غیر افزایش اتوماتیک ، ذخیره کنی و بعد مجددا اونو تبدیل کنی به فیلد اتوماتیک افزایشی