View Full Version : پیدا کردن تاریخهای بین دو تاریخ
tikzahraaran
جمعه 02 اسفند 1387, 14:46 عصر
با سلام خدمت دوستان گرامی می دانم که این موضوع خیلی تکراری است
و با یک جستجو می توانم آن را پیدا کنم
ولی خواهش می کنم اول متن را بخوانید
من در بانک اطلاعاتی ام یک جدول دارم که تاریخ را در آن را بر اساس رشته ذخیره می کنم
حال در دلفی دو ماسک ادیت گذاشته ام که تاریخ را از کاربر دریافت می کند و می خواهم با وصل شدن به اس کیو ال تاریخهایی که بین این دو تاریخ است را در گزارش نشان بدهم لطفا من را راهنمایی کنید البته از کد زیر استفاده کردم ولی پیغام خطا می دهد
Ddaftartafzili.ADOQuery1.Close;
Ddaftartafzili.ADOQuery1.SQL.Clear;
Ddaftartafzili.ADOQuery1.SQL.Add('select * from articldaeem where codetafzili=:codetafzili and shomaresanad between '''+'daftartafzili.edit2.Text'+''' and '''+'daftartafzili.Edit3.Text'+''' ');
Ddaftartafzili.ADOQuery1.Parameters.ParamValues['codetafzili']:=daftartafzili.edit1.Text;
Ddaftartafzili.ADOQuery1.Open;
و پیغام خطا هم این است
Syntax error converting the varchar value '1387/11/06' to a column of data type int
خواهش می کنم کمکم کنید
Unique
جمعه 02 اسفند 1387, 16:13 عصر
سلام
دوست عزیز ! اولا شما نیاز نداری که تاریخ را بصورت رشته کاراکتر ذخیره کنی ! به صورت integer ذخیره کن !
مثلا 1387/11/20 را به صورت 13871120 یادت باشه که حتما باید 8 رقمی ذخیره کنی ! مثلا ذخیره کن : 13871105 نه 1387115 ! بعدش اگه خواستی در زمان نمایش 1387/11/05 نمایش بده !
شما فقط در این صورت میتونی بین یه فاصله تاریخ را Select کنی ! Error ای هم که بهت میده اینه که نمیتونه
1387/11/06 را به یه عدد تبدیل کنه ! چون / یک کاراکتر غیر عددی هستش !
Unique
جمعه 02 اسفند 1387, 16:27 عصر
یادم رفت بگم که برای نمایش تاریخ به صورت 1387/11/05 از عدد 13871105 میتونی از کد زیر استفاده کنی :
strDate := inttostr(13871105)
strDate := copy(strDate,1,4) + '/' + copy(strDate,5,2) + '/' + copy(strDate,7,2);
امیدوارم مشکلت حل بشه !
mafazel
شنبه 03 اسفند 1387, 07:49 صبح
با سلام
فکر میکنم وقتی از نوع داده حرفی/رشته ای استفاده می کنید، حتما باید در مقادیر حدود از کوتیشن استفاده کنید.
کد زیر را امتحان کنید
...
Ddaftartafzili.ADOQuery1.SQL.Add('select * from articldaeem where codetafzili=:codetafzili and shomaresanad between '''+'daftartafzili.edit2.Text'+''' and '''+'daftartafzili.Edit3.Text'+''' ');
Ddaftartafzili.ADOQuery1.Parameters.ParamValues['codetafzili']:=QuotedStr(daftartafzili.edit1.Text);
Ddaftartafzili.ADOQuery1.Open;
یعنی همون طوری که در shomaresanad پارامتر ها را با کوتیشن دادید. (حتما آنها رشته هستند درسته؟)
دوست عزیز Unique با روش شما خیلی موافق نیستم. من و خیلی از دوستای دیگه تاریخ رو بصورت string ده تایی کار می کنیم مشکلی هم نداشته ایم. اگر مثال نقضی دارید لطفا بگید. ممنون
Unique
شنبه 03 اسفند 1387, 22:09 عصر
سلام
خدا وکیلی کد شما تمیز و خوندنی تره (رشته ای) یا کدی که با عدد باشه ؟ (نه کوتیشنی نه تو هم تو هم )
باید بگم من خودم تا 2 سال پیش Date را بصورت میلادی ذخیره میکردم و بعدش Convert میکردم !
تا اینکه توی یه پروژه دیدم از عدد استفاده کرده ! اونجا بود که ... (بقیش مهم نیست)
ببینید استفاده از رشته شاید جواب بده (تا حالا استفاده نکردم) ولی با چند ثانیه تفکر به این دو مشکل مخصوصا توی پایگاه های بزرگ رسیدم :
1- Pass کردن و محاسبات رشته ای توی Stored Procedure ها از عدد بسیار کند ترن !
2- تا اونجا که من کار کردم Index روی فیلد عددی سرعت بیشتری نسبت به رشته ای میده !
و شاید خیلی مشکلات دیگه که اگه هوس کنم یه روزی توی یه پروژه ای تستش کنم !
شما هم میتونید امتحانش کنین ضرر نداره !
vcldeveloper
یک شنبه 04 اسفند 1387, 00:52 صبح
ذخیره تاریخ با فرمت Date هم از نظر سرعت، و حجم داده ذخیره شده، بهینه تر از استفاده از حروف هست، هم توابع زیادی در سمت سرور و کلاینت برای کار با آنها، یا ویرایش آن وجود دارند. همچنین این قابلیت را هم داره که اعتبار تاریخ بطور خودکار بررسی میشه، و برنامه نویس لازم نیست برای این کار کدی بنویسه.
برای نمایش تاریخ میلادی ذخیره شده بصورت تاریخ شمسی هم چند روش وجود داره:
1- اگر داده تاریخ فقط خواندنی هست، میشه با نوشتن یک User Function در سمت بانک اطلاعاتی، در داخل کوئری ها، یا SPها از آن برای تبدیل تاریخ میلادی به شمسی، و برگرداندن یک فیلد رشته ایی استفاده کرد.
2- اگر لازم هست که مقدار موجود در فیلد ویرایش شود، می توان:
2-1- از رویدادهای OnGetText و OnSetText مربوط به TField استفاده کرد.
2-2- یک نوع فیلد جدید (مشتق شده از TField) ایجاد کرد که کار تبدیل را بطور خودکار انجام می دهد (مثل کاری که Farsi Components یا xCalendar انجام میدند.)
2-3- در صورتی که لزومی ندارد تاریخ در داخل Grid نمایش داده شود، یا ویرایش شود، و باید در یک کنترل Edit یا DateTimePicker نمایش داده شود، می توان کنترل هایی برای این منظور ایجاد کرد که ورودی آنها TDateField باشد، و متناسب با نیاز برنامه نویس، ورودی را به تاریخ شمسی یا میلادی نمایش بدهد (مثل کاری که Farsi Components، یا xCalendar یا Solar Calendar انجام میدند.)
mafazel
دوشنبه 05 اسفند 1387, 10:55 صبح
از توجه دوستان تشکر می کنم
شکی نیست که فیلد عددی سرعت بالا تری داره اما معمولا روی تاریخ ایندکس نمی زنند. استفاده از نوع DateTime هم اصولی تره (یا رومی روم یا زنگی زنگ). در عین حال همه ما مجبوریم یک سری پردازش های اضافی برای تبدیل تاریخ انجام بدیم.
درسته که محاسبات و جستجو در متغیر متنی کند تره اما از اونجا که ما محاسبات زیادی روی تاریخ نداریم استفاده از فیلد متنی کندی زیادی نداره و با توجه به این که اگر متنی کار کنیم در هر Query لازم نیست تبدیل رو انجام بدیم اینجا کندی نداریم. منتها عیب این روش اینه که کمی حجم بیشتری میگیره که به نظر من مهم نیست. پیچیدگی رو کم میکنه.
Unique
دوشنبه 05 اسفند 1387, 12:47 عصر
معمولا روی تاریخ ایندکس نمی زنند
از کجا این حرف را میزنین ؟ (گرچه میدونم ربطی به بحث Delphi نداره اما میخوام کسی اگه این تاپیک را زمانی خوند بدونه اگه قصد استفاده از تاریخ به صورت میلادی را نداره ! بهتره از عدد استفاده کنه یا رشته ؟)
من بار ها روی جداول چند صد هزار رکوردی مثلا زمانی که میخوای مقادیر بین دو تاریخ یا کمتر و بیشتر و حتی یک تاریخ خاص را پیدا کینی با تعریف ایندکس برای فیلد تاریخ (حالا میلادی یا عددی) سرعت را چند برابر کردم.
اما از اونجا که ما محاسبات زیادی روی تاریخ نداریم استفاده از فیلد متنی کندی زیادی نداره
بار ها پیش میاد که نیاز هست تاریخ بعد یا قبل از یک تاریخ را توی Stored Procedure ها ویا حتی خود دلفی محاسبه کنیم ! یا هر عملیاتی روی تاریخ انجام بدیم ! گرچه منظور من عملیاتی بود که خود پایگاه روی اون فیلد حالا به صورت شرطی یا محاسباتی انجام میده !
توجه به این که اگر متنی کار کنیم در هر Query لازم نیست تبدیل رو انجام بدیم اینجا کندی نداریم
خیلی از مواقع یک تابع کوچیک که تبدیل را انجام میده واقعا به صرفه تر از افزایش حجم ! سرعت انجام تراکنش ها - سرعت Process و غیره هستش ...
در ضمن من جاهایی هم دیده بودم که تاریخ را همون هشت تایی اما String ذخیره میکنند! اما برای جالبه که با وجود "/" چطور میشه یک بازه را تشخیص بده ! آیا MSSQL اینجوریه یا همه پایگاه ها اینجوری عمل میکنند ؟
DelphiFriend
چهارشنبه 21 اسفند 1387, 20:47 عصر
شما میتونید از کد زیر هم استفاده کنید.
ADOTable1.Filter:='data>='''+edit1.Text+''' and data<='+edit2.Text;
ADOTable1.Filtered:=true;
موفق باشی.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.