2009-11-23 23 views
0

我有一个DATETIME列“EntryDate”,我将值存储为dd/MM/yyyy格式。 但是当我通过SQL获取记录时,我没有得到预期的结果。SQL Server中的dd/MM/yyyy

对于前:

我从日期23/10/2009 90个记录23/11/2009。我只得到5-10条记录。为什么是这样 ?

这里是我的查询:

SET DATEFORMAT DMY; 
SELECT * FROM salesorderlist so 
LEFT JOINT sites s ON s.id = so.siteid 
WHERE so.entrydate between '23/10/2009' and '23/11/2009' 
ORDER BY so.entryDate DESC 

但是,当我把日期范围为23/10/2009 31/10/2009到我得到正确的结果,如果我给的日期范围从23/10/2009至01/11/2009我连一行都没有。

我缺少什么?

在数据库中,我将值存储为“31/10/2009”(dd/MM/yyyy)格式。

在此先感谢。

已经做了一个错误..
Entrydate是Varchar列。现在改成了Datetime.Thanks专家的帮助

我现在有一个更大的问题...我如何VARCHAR列转换为datetime列...如何更新表

当我尝试更改数据类型,我得到的错误: char数据类型转换为日期时间数据类型导致超出范围的日期时间值。 该声明已被终止。

我不想删除记录,因为有成千上万的记录。是否有任何方法可以转换? 谢谢

+0

是什么类型的数据库so.entrydate? – pjp 2009-11-23 09:16:22

回答

4

如果要存储您的日期为DATETIME数据类型,那么我会尝试使用ISO-8601的日期格式(YYYYMMDD)用于任何疑问:

SELECT ...... 
WHERE so.entrydate BETWEEN '20091023' and '20091123' 

这种格式是独立于任何日期的格式设置,并且始终能够工作 - 不管日期在SQL Server计算机上的格式如何。

此外,您需要记住DATETIME还存储TIME - 因此上述查询将仅返回那些截至2009年11月23日0:00小时的记录 - 它将在而不是之间显示任何内容天!

如果你想有一个BETWEEN查询直至并包括全部Nov-23,2009年,你需要指定:

SELECT ...... 
WHERE so.entrydate BETWEEN '20091023' and '20091123 23:59:59' 

或者只是使用“20091124”作为你的第二个条件 - 那么你得到的一切行动并且包括前一天(11月23日)的最后一秒。

如果您使用的是SQL Server 2008,那么您还可以查看新的DATE数据类型,它仅存储仅含日期的数据 - 并且使这些查询变得更容易! (除了占用更少的空间外)。

UPDATE:

要转换现有的表,我这样做:

  • 创建类型的新列“MyNewDateTime” DATETIME
  • 在你的表中的所有转换运行脚本田野:

    UPDATE dbo.salesorderlist 
    SET MyNewDateTime = CONVERT(DATETIME, EntryDate, 103) 
    

这应该将您的“dd/mm/yyyy”样式日期字符串转换为DATETIME并将其存储在新列中。一旦这样做了,你可以删除旧的列

ALTER TABLE dbo.salesorderlist DROP COLUMN EntryDate 

,并重新命名新一旧名称(如果你想):

EXEC sys.sp_rename @objname = 'dbo.salesorderlist.MyNewDateTime', 
        @newname = 'EntryDate', 
        @objtype = 'COLUMN' 

马克

+0

非常感谢。现在plz帮助我与转换 – 1984 2009-11-23 09:47:32

3

它看起来像你正在以文本格式存储你的日期,在这种情况下返回的结果集是正确的(因为23/11/2009几乎直接后面23/10/2009如果你排序相同长度字符串字母数字)。

除非你有充分的理由不这样做,否则你应该总是将日期存储为日期,数字存储为数字等等。

3

我想你正在将数据存储为varchar。

在字符串比较中,'23/10/2009'和'23/11/2009'与第5个字符相同。

你应该

  • 使用年月日的日期文字(YYYY-MM-DD新的SQL 2008的)日期+时间数据类型
+0

无法将日期时间字段转换为varchar。您知道任何转换方法吗? – 1984 2009-11-23 10:01:06

+0

这个问题明确指出,数据存储为DATETIME而不是varchar()? – 2009-11-23 10:09:31

+0

@Mitch:检查问题更新时间与先前答案的时间。 – gbn 2009-11-23 10:39:44

2

只是为了您的信息

  • 使用一个:假设该列实际上是DateTime(其他人建议您可能使用的是文本列)的,则不需要“以X格式存储日期值”。日期值使用内部格式存储在数据库中。日期格式仅在检索数据时才起作用。

    话虽如此,你的日期是否有时间值?如果您的日期对应于23/11/2009,但时间值不同于0:00:00,则这些日期不会显示在您的查询中。您应该指定类似'23/11/2009 23:59:59.999'之类的内容。

    无论如何,构建像这样的查询通常不是一个好主意,在查询本身中对where子句的参数进行硬编码(这很容易出错并且可能会无意中打开依赖注入攻击的大门)。相反,您应该使用您正在使用的数据库访问引擎的参数机制(如果您使用ADO.NET,请参阅此处的示例:http://www.csharp-station.com/Tutorials/AdoDotNet/lesson06.aspx

  • 0

    除非您给时间它将使用非常一天的开始如此“日期< 23/11/2009”将不包括23日的任何条目。这有帮助吗?

    也许你的连接并没有产生你的想法 - 试着在按照日期限制它之前查看中间表。

    如果您发布表中的数据,我可以尝试帮助更多。

    +0

    感谢您的帮助 – 1984 2009-11-23 09:46:59

    0

    要转换的列数据我通常做以下类型

    ALTER TABLE salesorderlist ADD entrydate2 datetime 
    GO 
    UPDATE salesorderlist SET entrydate2=CAST(entrydate AS datetime) 
    GO 
    ALTER TABLE salesorderlist DROP COLUMN entrydate 
    GO 
    EXEC sp_rename 'dbo.salesorderlist.entrydate2', 'entrydate', 'COLUMN' 
    GO 
    
    -1

    对于转换你的专栏,我建议你先改变公司列的内容使用明确的格式(yyyymmdd或yyyy-mm-ddThh:mm:ss,具有明显的含义,但T只是字面意义上的字母T),然后执行alter table语句。

    0

    使用此 - >

    SET DATEFORMAT DMY;SELECT * FROM salesorderlist so LEFT JOINT sites s ON s.id = so.siteidWHERE so.entrydate between convert(varchar, '23/10/2009',101) and convert(varchar, '23/11/2009', 101) ORDER BY so.entryDate DESC