PDA

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



ELABAA
چهارشنبه 25 دی 1387, 22:25 عصر
سلام دوستان
یه سوال داشتم :
من می خواهم قبل از اینکه داده ای رو به دیتابیسم که اس کیو ال هست
درج کنم ببینم که آیا این داده قبلا به دیتابیسم وارد شده یا نه اگه وارد
شده باشدبه کاربرم پیام بده که این مقدارقبلا وارد شده و آن مقداررا
وارد دیتابیسم نکنه در غیر این صورت داده ام رو به دیتابیس وارد بکنه
عقلم به جایی قد نمی ده لطفا با یه مثال کوچولو کمکم کنین:گریه:
با تشکر
ELABAA

ghabil
پنج شنبه 26 دی 1387, 02:44 صبح
از تعریف ایندکس Unique روی اون فیلد(ها) توی دیتابیس استفاده کن، کل ماجرا (هم تعریف ایندکس یونیک و هم ابدیل پیام خطای دیتابیس به یک خطای کاربر پسند) قبلا توضیح داده شده جستجو کن.

ELABAA
پنج شنبه 26 دی 1387, 17:00 عصر
سلام دوستان
یه همچین راه حلی نوشتم واسه خودم ولی خطای زیر را به دستوری که علامت زدم بهم میده چیکار کنم

لطفا راهنمایی ام کنین


with adoTable1 do
begin


if (edit1.Text='')or(edit2.Text='') then
('لطفا تمام موارد را کامل کنین') ShowMessage


(else if Locate('code_calleg',Edit1.Text,[]) = True
or(Locate('name_calleg',Edit2.Text,[]) = True) ) then
('این اطلاعات قبلا وارد شده') ShowMessage


( else if (Locate('code_calleg',Edit1.Text,[]) = false
or(Locate('name_calleg',Edit2.Text,[]) = false) then


; Insert
; FieldByName('code_calleg').AsString := Edit1.Text
; FieldByName('name_calleg').AsString := Edit2.Text
; Post
;('درج شد')ShowMessage
; end



متن خطا


Project Project1.exe raised exception class EDatabaseError with message 'ADOTable1: Dataset not in edit or insert mode'. Process stopped. Use Step or Run to continue.


البته باید این رو هم بگم که این خطا رو زمانی بهم میده که به هر دو یا یکی از edit هام مقداری وارد نشده باشد ...
اینم بگم که اول این پیام ___'لطفا تمام موارد را کامل کنین' ___ رو میده بعد خطای بالایی رو میده ! ! ! ! !



باتشکر

ghabil
پنج شنبه 26 دی 1387, 18:36 عصر
بجای ShowMessage(('لطفا تمام موارد را کامل کنین') بنویس :
[code]
raise Exception.Create('لطفا تمام موارد را کامل کنین')
[/cdoe]

ایجاد یک حطا موجب میشه ادامه روند برنامه متوقف بشه.

ELABAA
پنج شنبه 26 دی 1387, 22:01 عصر
بجای ShowMessage(('لطفا تمام موارد را کامل کنین') بنویس :
[code]
raise Exception.Create('لطفا تمام موارد را کامل کنین')
[/cdoe]

ایجاد یک حطا موجب میشه ادامه روند برنامه متوقف بشه.


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

Process .'لﻄفا ﺗمام ﻣﻮارد را کاﻣﻞ کنﯿﻦ' exe raised exception class Exception with message.Project Project1 stopped. Use Step or Run to continue.

ghabil
جمعه 27 دی 1387, 18:44 عصر
خب باید خطا بده دیگه این حطایی که خودت درست میکنی که کاربر ببینه تمام موارد رو کامل نکرده، وقتی برنامه رو خارج از دلقی اجرا کنی کاربر فقط خطای فارسی رو میبینه بعدش هم میفهمه که باید همه فیلدهارو پر کنه

bmanfy
شنبه 28 دی 1387, 12:21 عصر
من قبلنا خودم از روشهای زیر استفاده می کردم .
یکی اینکه اول جستجو میکردم بعد ثیت . مثلا میخوای فیلد Id تکراری نباشه .
با فرض بر اینکه مقدار id جدید رو هم داری توی Edit_id وارد میکنی و با فرض بر اینکه به AdoTable1 وصل شدی .


if Not AdoTable1.Locat(id , Edit1.Text , [] ) then
begin
AdoTable1.Append ;
.
.
AdoTable1.Post ;
end
Else
ShoMessage ('کد تکراری است! ' ) ;


یه کار هم که بعدها ترها انجام میدادم :


Try
AdoTable1.Append ;
.
.
AdoTable1.Post ;
Ecxept
AdoTable1.Cancel ;
ShowMessage ('کد تکراری است! ' ) ;
End ;

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

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



Var Filter : String ;
Begin
Filter := '(id=' + edit_id.text + ') and(name = ' + Q...(edit_name.text) + ')' ;
AdoTable.Filter := Filter ;
AdoTable1.Filtered := True ;
if Not AdoTable1.RecordCount Then
begin
در اینجا ثبت اطلاعات رو انجام میدی .
end
Else
در اینجا هم که پیام رو نشون میدی ک
AdoTable1.Filtered := False ;
end ;


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

ghabil
شنبه 28 دی 1387, 19:31 عصر
دوست عزیز روش درست و کامل همون ایندکس گزاری هست، شما وقتی از یک RDBMS در برنامتون استفاده میکنید باید قوانین مربوط بهش رو توسط خودش مدیریت کنید

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



if Not AdoTable1.Locat(id , Edit1.Text , [] ) then
begin
AdoTable1.Append ;
.
.
AdoTable1.Post ;
end
Else
ShoMessage ('کد تکراری است! ' ) ;



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



یه کار هم که بعدها ترها انجام میدادم :


Try
AdoTable1.Append ;
.
.
AdoTable1.Post ;
Ecxept
AdoTable1.Cancel ;
ShowMessage ('کد تکراری است! ' ) ;
End ;



ابن روش هم که غلط هست ، دلیلش اینه که مثلا اگر یک فیلد رو مقدار دهی هم نکرده باشید و مثلا خطلای NOT NULL بگیرید بازهم پیام تکراری بودن میگیرید، در ین روش شما باید از متن خطا رو بگیرید و چک کنید تا در کنار استفاده از ایندکس روش درست و کامل بشه.
از طرف دیگه هیچ وقت جایی که باید خطا Raise بشه تبدیلش نکنید به ShowMessage مگر منطقی پشتش باشه...





Var Filter : String ;
Begin
Filter := '(id=' + edit_id.text + ') and(name = ' + Q...(edit_name.text) + ')' ;
AdoTable.Filter := Filter ;
AdoTable1.Filtered := True ;
if Not AdoTable1.RecordCount Then
begin
در اینجا ثبت اطلاعات رو انجام میدی .
end
Else
در اینجا هم که پیام رو نشون میدی ک
AdoTable1.Filtered := False ;
end ;


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

این روش هم که دیگه از اون روشهاست! در کنار همه مشکلاتی که Locate داشت ، این روش به مراتب کند تر هست! توی User Interface تاثیر میزاره و از همه بدتر چون فیلتر کردن رو توی TRY نزاشتی اگه زمان درج اطلاعات به خطا بخوری جدولت فیلتر شده باقی میمونه!
خب توکه میخوای این کار رو بکنی همون Locate میکردی روی دوتا فیلد.

bmanfy
یک شنبه 29 دی 1387, 18:13 عصر
اولا وقتی فیلد رو ایندکس میکنید ، به علت اینکه براش ایندکس ساخته میشه پس این چک کردن بصورت اکسپنشال با افزایش دیتا سریعتر میشه ، دوما اگر همزمان دو نفر مشغول افزودن دیتا باشند و جفتشون قبل از ریفرش کردن دیتا رو پست بکنند این کد هیچ خطایی نمیگیره و شما اطلاعات تکراری خواهید داشت.

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



ابن روش هم که غلط هست ، دلیلش اینه که مثلا اگر یک فیلد رو مقدار دهی هم نکرده باشید و مثلا خطلای NOT NULL بگیرید بازهم پیام تکراری بودن میگیرید، در ین روش شما باید از متن خطا رو بگیرید و چک کنید تا در کنار استفاده از ایندکس روش درست و کامل بشه.
از طرف دیگه هیچ وقت جایی که باید خطا Raise بشه تبدیلش نکنید به ShowMessage مگر منطقی پشتش باشه...

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


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

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

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

ghabil
یک شنبه 29 دی 1387, 22:20 عصر
حوصله بحث که ندارم به دلایلی که گفتم روش درست ایندکس گزاری هست روشهای دیگه هرکدوم در شرایطی مشکل ساز میشند. حالا ممکنه شما در ذهن خودتون خیلی چیزها رو در نظر بگیرید یا نگیرید ...
قبلا اینجا بارها توضیح دادم که آموزش روشهای ساده اما ناقص به کاربران موجب میشه که بعدا به مشکلات بزرگتر بخوردند و بعدا، هم پیدا کردن مشکل براشون سخت تر میشه هم رفعش.

bmanfy
دوشنبه 30 دی 1387, 09:16 صبح
حوصله بحث که ندارم به دلایلی که گفتم روش درست ایندکس گزاری هست روشهای دیگه هرکدوم در شرایطی مشکل ساز میشند. حالا ممکنه شما در ذهن خودتون خیلی چیزها رو در نظر بگیرید یا نگیرید ...

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


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

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

به هر حال خیلی هم ممنونم از اینکه نظراتتون رو دادین . امیدوارم حرفهام باعث نارحتی تون نشده باشه .

ghabil
پنج شنبه 03 بهمن 1387, 09:29 صبح
اما شما که اینقدر مقیدی که باید بهترین راه گفته بشه لااقل یه خط کد مینوشتی تا همه بهره ببرند .


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

bmanfy
پنج شنبه 03 بهمن 1387, 09:44 صبح
من تعچب میکنم چرا وقتی تجربیات اینجوری رو که واقعا بدست آوردنشون به این راحتیها نیست رو با دوستان در میون میزاریم جتی وقت میزاریم و توضیح میدیم که چرا روشها دیگه بهینه نیست، دوستان بجای استقبال اینطوری جبهه گیری میکنند!

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

accpascal
شنبه 26 بهمن 1387, 22:42 عصر
سلام دوستان
یه همچین راه حلی نوشتم واسه خودم ولی خطای زیر را به دستوری که علامت زدم بهم میده چیکار کنم

لطفا راهنمایی ام کنین


with adoTable1 do
begin


if (edit1.Text='')or(edit2.Text='') then
('لطفا تمام موارد را کامل کنین') ShowMessage


(else if Locate('code_calleg',Edit1.Text,[]) = True
or(Locate('name_calleg',Edit2.Text,[]) = True) ) then
('این اطلاعات قبلا وارد شده') ShowMessage


( else if (Locate('code_calleg',Edit1.Text,[]) = false
or(Locate('name_calleg',Edit2.Text,[]) = false) then


; Insert
; FieldByName('code_calleg').AsString := Edit1.Text
; FieldByName('name_calleg').AsString := Edit2.Text
; Post
;('درج شد')ShowMessage
; end



متن خطا


Project Project1.exe raised exception class EDatabaseError with message 'ADOTable1: Dataset not in edit or insert mode'. Process stopped. Use Step or Run to continue.


البته باید این رو هم بگم که این خطا رو زمانی بهم میده که به هر دو یا یکی از edit هام مقداری وارد نشده باشد ...
اینم بگم که اول این پیام ___'لطفا تمام موارد را کامل کنین' ___ رو میده بعد خطای بالایی رو میده ! ! ! ! !




باتشکر

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



or(Locate('name_calleg',Edit2.Text,[]) = false) then
begin


; Insert
; FieldByName('code_calleg').AsString := Edit1.Text
; FieldByName('name_calleg').AsString := Edit2.Text
; Post
end;
;('درج شد')ShowMessage

اصغر (پآچ)
چهارشنبه 30 بهمن 1387, 12:21 عصر
سلام دوستان

من با اندیکس گذاری یکم مشکل دارم! مشکلم اینجاست که من توی بانکم دو تا فیلد دارم که یکی شماره درخواست و دیگری تاریخ درخواسته، توی بانکم نباید شماره درخواست تکراری ثبت بشه یعنی یک درخواست با شماره مشخص فقط در یک روز از سال ثبت بشه واضحتر بگم یعنی درخواست شماره 123 با تاریخ 30/11/87 توی بانکم یکتا باشه حالا درخواست شماره 123 با تاریخ 30/11/86 یا درخواست شماره 123 با تاریخ 23/11/87 بتونه توی بانکم ذخیره بشه اما اگه من بیام این دوتا فیلد رو ایندکس کنم به مقادیر تکرار گیر میده و توی برنامه خطا ایجاد میشه!

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

موفق و موید باشید.

اصغر (پآچ)
شنبه 03 اسفند 1387, 13:47 عصر
سلام

کسی در این باره کمک نظر راهکار و ... نداره؟

موفق و موید باشید

negiiin
سه شنبه 18 فروردین 1388, 11:49 صبح
با سلام خدمت دوستان
من هم مشکل کاربر عزیر elabaa را دارم ولی از راهنمایی شما سر در نیاوردم . من از filter استفاده نمیکنم چون میخوام با sql کار کنم. خواهشا راهنمایی بفرمایید مساله حیاتی است.

begin
ado1.Close;
ado1.CommandText:='select [id],[code],[h]* 10 as u from table1 where id='+quotedstr(trim(edit1.Text));
ado1.Open;
ado2.Open;
ado2.Insert;
ado2.First;
ado1.First;
while not ado1.Eof do
begin
ado2.Insert;
ado2['id1']:=ado1['id'];
ado2['cpde1']:=ado1['code'];
ado2['h1']:=ado1['u'];
ado2.Next;
ado1.Next;
end;
ado2.Post;
ado1.First;
ado3.First;
while not ado1.Eof do
begin
if pos(ado1['cpde1'],ado3['code'])=1 then
begin
ado3.edit;
ado3['kl']:=ado1['h1'];
end;
ado2.Next;
ado3.Next;
end;
ado2.Post;
ado3.Post;
end;

bmanfy
سه شنبه 18 فروردین 1388, 19:29 عصر
دوست عزیز برای نوشتن کد از تگ مخصوصی که مشخص شده استفاده کنید تا کدهاتون به این شکل نشون داده نشه . چون واقعا حوصله میخواد که کسی بشینه اینا رو بخونه .
اما خوب با Sql که حتی خیلی راحت تره .
کافیه با استفاده از Exists وجود یه رکود خاص با خبر بشی .


if Exists (Seletc Id From Tbl where Id=Value)
.

این دستور کلی اونه برای Sql اما دیگه اینکه بخوای به چه طریقی از دستور استفاده کنی به خودت برمیگرده .
مثلا میتونی از این دستور توی یه Query استفاده کنی .