PDA

View Full Version : مشکل بازیابی تاریخ-سی شارپ



maxwel
شنبه 30 خرداد 1394, 13:44 عصر
سلام
دوستان یه یه مشکلی واسم پیش اومده که هیچ راه برگشتی ندارم
من تاریخ رو به صورت nvarchar وبه این شکل "1394/2/3" تو sql ذخیره کردم و وقی خواستم یک سری اطلاعات رو از تو یه بازه بگیرم بعضی از تاریخ ها نشون داده نمیشه
برای مثال وقتی میزنم که از 1394/2/1 تا 1394/2/31 را select کنه بعضی از تاریخ ها توشون نیست مثل 1394/2/4
ولی وقتی بازه رو کوچکتر می کنم مثلا 1394/2/1 تا 1394/2/6 همشونو نشون میده

Mahmoud Zaad
شنبه 30 خرداد 1394, 14:00 عصر
سلام
با این فرمت امتحان کنید: 1394/02/01 یا 1394/02/31 یا 1394/02/04 یعنی روزها یا ماه هایی که یک رقمی هستند رو یه 0 به اولشون اضافه کنید. در روشی که شما ذخیره کردید تاریخ های بین 1394/2/1 و 1394/2/3 رو در نظر میگیره و select میکنه نه 1394/2/31

maxwel
شنبه 30 خرداد 1394, 14:08 عصر
ممنون از جوابتون
فرمت تاریخ ها یه اشتباهی که کردم به صورت 1394/2/1 است راهی نیست تو select کردن فرمتشونو تغییر بدم؟
و ببخشید منظور تونو از این جمله نفهمیدم"
در روشی که شما ذخیره کردید تاریخ های بین 1394/2/1 و 1394/2/3 رو در نظر میگیره و select میکنه نه 1394/2/31"

Mahmoud Zaad
شنبه 30 خرداد 1394, 14:24 عصر
فرمت تاریخ ها یه اشتباهی که کردم به صورت 1394/2/1 است راهی نیست تو select کردن فرمتشونو تغییر بدم؟

اینکه مستقیماً تو کوئری بخواید تغییرات رو اعمال کنید، الان چیزی به ذهنم نمی رسه.


و ببخشید منظور تونو از این جمله نفهمیدم"
در روشی که شما ذخیره کردید تاریخ های بین 1394/2/1 و 1394/2/3 رو در نظر میگیره و select میکنه نه 1394/2/31"

ببینید شما اگه به صورت آزمایشی یه فیلد رو از نوع nvarchar بگیرید بعد توش اعداد از 1 تا 100 رو ذخیره کنید وقتی دستور sort رو بدید به صورت زیر sort انجام میشه:

1، 10، 11، 12 ... 2، 20، 21، 22، ... 3، 30، 31 ...4، 40، 41، ...

یعنی رشته ها با هم مقایسه میشن نه اعداد! بنابراین در اینجا هم شما میگید تاریخ های بین 1 تا 31 اردیبهشت رو استخراج کنه ولی در این نوع داده ای عدد 4 بعد از عدد 31 قرار میگیره یعنی در بازه مد نظر شما قرار نمی گیره. ولی اگه یه 0 به سمت چپ اضافه بشه این مشکل حل میشه.

maxwel
شنبه 30 خرداد 1394, 15:04 عصر
اینکه مستقیماً تو کوئری بخواید تغییرات رو اعمال کنید، الان چیزی به ذهنم نمی رسه.

ببینید شما اگه به صورت آزمایشی یه فیلد رو از نوع nvarchar بگیرید بعد توش اعداد از 1 تا 100 رو ذخیره کنید وقتی دستور sort رو بدید به صورت زیر sort انجام میشه:

1، 10، 11، 12 ... 2، 20، 21، 22، ... 3، 30، 31 ...4، 40، 41، ...

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

golbafan
شنبه 30 خرداد 1394, 16:06 عصر
سلام راهش اینه که فرمت رو در دیتابیس تغییر بدید
باید با توابع استرینک کار کنید

باید ابتدا اعداد رو جدا کنید:
1394/2/14 => 1394 و 2 و 14
بعد باید فرمت رو اصلاح کنید

1394 => 0000 => 1394
2 => 00 => 02
14 => 00 => 14

بعدش به هو بچسبونید
1394+'/'+02+'/'+14

وقتی دیتابیس رو اصلاح کردی بعدش میتونی با فرمت yyyy/mm/dd جستجو کنی

برای جدا سازی:

DECLARE @old VARCHAR(10) = '1394/2/4'
DECLARE @y INT
SET @y = SUBSTRING(@old, 1, CHARINDEX('/', @old)-1)
DECLARE @md VARCHAR(5)
SET @md = SUBSTRING(@old, CHARINDEX('/', @old)+1, 5)
DECLARE @m INT
SET @m = SUBSTRING(@md, 1, CHARINDEX('/', @md)-1)
DECLARE @d INT
SET @d = SUBSTRING(@md, CHARINDEX('/', @md)+1,2)
select @y,@m,@d;

alireza264
شنبه 30 خرداد 1394, 16:46 عصر
سلام
مشکلت پیچیده تر از ایناست چون اگه یه نفر تاریخ رو یه بار بصورت 94/1/2 و یه یه بار 94/01/02 یا 94/1/02 وارد کنه اینا باهم یکسان در نظر گرفته نمیشن بنظر من یه قطغه کد بنویس و یه فیلد از نوع تاریخ به جدولت اضافه کن و بعد با خوندن فیلد اولی این جدیده رو پر کن


SqlConnection _Conn = new SqlConnection(CStr);

// Open the Database Connection
_Conn.Open();

try
{
SqlCommand _CmdUpdateTable1 = new SqlCommand(@"Alter Table Mytable ADD NewDate Date ", _Conn);
_CmdUpdateTable1.ExecuteNonQuery();
}
catch () { }

golbafan
شنبه 30 خرداد 1394, 16:59 عصر
این هم کد کامل:
با استفاده از این روش دیگه مهم نیست تاریخ چطوری وارد بشه:
1394/02/4
یا
1394/2/04
یا
1394/2/4
یا
1394/02/04
دیگه فرقی نداره

DECLARE @old VARCHAR(10) = '1394/2/4'
DECLARE @y INT
SET @y = SUBSTRING(@old, 1, CHARINDEX('/', @old)-1)
DECLARE @md VARCHAR(5)
SET @md = SUBSTRING(@old, CHARINDEX('/', @old)+1, 5)
DECLARE @m INT
SET @m = SUBSTRING(@md, 1, CHARINDEX('/', @md)-1)
DECLARE @d INT
SET @d = SUBSTRING(@md, CHARINDEX('/', @md)+1,2)
SELECT RIGHT('0000'+ CONVERT(VARCHAR,@y),4)+'/'+RIGHT('00'+ CONVERT(VARCHAR,@m),2)+'/'+RIGHT('00'+ CONVERT(VARCHAR,@d),2);

132443

ali_md110
شنبه 30 خرداد 1394, 18:50 عصر
میتونید کمی خلاصه تر هم بنویسید Shamsi نام فیلد تاریخ هست


SELECT RIGHT('0000'+ CONVERT(VARCHAR,DATEPART(yyyy, Shamsi)),4)+'/'+RIGHT('00'+ CONVERT(VARCHAR,DATEPART(mm, Shamsi)),2)+'/'+RIGHT('00'+ CONVERT(VARCHAR,DATEPART(dd, Shamsi)),2)from yourTable;

asman.abi
یک شنبه 31 خرداد 1394, 10:41 صبح
راحت ترین راهی که سراغ دارم.
برای تاریخ سه مولفه داریم. سال/ ماه/ روز
برای این سه مولفه 3 رکورد در جدول بساز. و برای مقایسه می تونی تک تک باهاشون برخورد کنی و اعمالت رو انجام بدی.

golbafan
یک شنبه 31 خرداد 1394, 10:51 صبح
میتونید کمی خلاصه تر هم بنویسید Shamsi نام فیلد تاریخ هست


SELECT RIGHT('0000'+ CONVERT(VARCHAR,DATEPART(yyyy, Shamsi)),4)+'/'+RIGHT('00'+ CONVERT(VARCHAR,DATEPART(mm, Shamsi)),2)+'/'+RIGHT('00'+ CONVERT(VARCHAR,DATEPART(dd, Shamsi)),2)from yourTable;


سلام فکر کنم تابع DATEPART برای کار با تاریخ باشه و فیلد تاریخ ایشون VARCHAR هست

maxwel
چهارشنبه 03 تیر 1394, 11:57 صبح
ممنون از کمک هاتون این تابع رو نوشتم حل شد
create function split(@date nvarchar(max))


returns nvarchar(max)
as
begin
declare @sal nvarchar(5)=substring(@date,1,5)
declare @n nvarchar(5)=right(@date,len(@date)-5)


declare @t nvarchar(5)=substring(@date,6,len(@date))
declare @y int
declare @mah nvarchar(5)
declare @day nvarchar(5)
set @y=CHARINDEX('/',@t)
set @mah=SUBSTRING(@t,1,@y-1)
set @day=SUBSTRING(@n,@y+1,LEN(@n))
if(LEN(@mah)=1)
begin
set @mah='0'+@mah
end
if(LEN(@day)=1)
begin
set @day='0'+@day
end
return (@sal+@mah+'/'+@day)
end