在日期之间获取数据

时间:2015-12-22 13:25:13

标签: c# sql-server

所以,我想在mssql中的两个日期之间检索数据。我有一张桌子,名字是FILES。我有2列,名称是NAME,RECORDDATE(nvarchar)。当我保存我的数据时,我从raddatetimepicker.text获取所以我的值是" 2015年12月22日星期二"。

我的查询是

select * from FILES where RECORDDATE>= '11 January 2015 Saturday' and RECORDDATE<= '24 October 2015 Monday'

这个查询有效,但是当我在2015年1月11日星期六更改&#39;到2015年1月28日周二&#39;它不起作用。它是如此有趣,因为我在1月21日的查询也工作但是当我写1月28日我得到0行。

我真的卡住了,不知道问题。

你的答案是真实的,但其他答案也是如此,所以我不知道如何将所有答案标记为答案:)谢谢你。这是我在一个月的自我训练后的第一个项目,所以不要太惊讶:D

6 个答案:

答案 0 :(得分:1)

以下情况属实,条件是您的DATETIME实际上是数据库中的DATETIME字段。您目前将NVARCHAR作为DateTimePicker存储。 现在停止执行此操作并使用正确的类型!

任何DateTime都应该有一个返回DateTime recordDate = dtpDate.Value; using (SqlCommand cmd = new SqlCommand("insert into FILES (NAME, RECORDDATE) VALUES (@name, @recorddate)", conn)) { cmd.Parameters.Add("@name", SqlDbType.NVarChar).Value = someName; cmd.Parameters.ADd("@recorddate", SqlDbType.DateTime).Value = recordDate; cmd.ExecuteNonQuery(); } 的属性。如果没有:转储并使用正确的。也就是说,您可以使用参数化查询来存储和查找您的记录。

插入将如下所示:

DateTime start = dtpStart.Value;
DateTime end = dtpEnd.Value;

using (SqlCommand cmd = new SqlCommand("select * from FILES where RECORDDATE BETWEEN @start and @end", conn))
{
    cmd.Parameters.Add("@start", SqlDbType.DateTime).Value = start;
    cmd.Parameters.Add("@end", SqlDbType.DateTime).Value = end;

    using (SqlDataReader reader = cmd.ExecuteReader())
        ...
}

然后查询查询归结为:

String.Format

这样做可以解决以下问题:

  1. 如果使用{{1}}或类似的东西插入参数,则可以进行SQL注入。
  2. 不同的日期格式并不重要,因为.NET会将日期正确转换为SQL服务器理解的内容

答案 1 :(得分:0)

实际上你得到字符串比较,而不是日期比较,因为RECORDDATE是NVARCHAR(unicode字符串)。

第一个字符串以&#39; 28开始。&#39;所以它比以&#39; 24&#39;开头的字符串更大,所以你总是假的,因此是0行。

看看这个答案:https://stackoverflow.com/a/1411081/2811743

答案 2 :(得分:0)

由于将日期存储为字符串,您正在执行字符串比较,而不是日期比较。当您更新了值后,您正在检查28 January 2015 Tuesday24 October 2015 Monday之间的字符串。鉴于较低的值更大,您将永远不会返回任何行。

如果要查找两个日期之间的值,最好将数据类型更改为DateTime

如果无法做到这一点,那么您可以将列转换为DateTime,例如

SELECT * FROM FILES 
WHERE RECORDDATE >= CAST('11 January 2015 Saturday' AS DATETIME) 
    AND RECORDDATE <= CAST('24 October 2015 Monday' AS DATETIME)

作为旁注,2015年1月28日是星期三,而不是星期二

此方法的一个缺点是您将无法在RECORDDATE列上使用索引,因为查询将是非SARGable

答案 3 :(得分:0)

在您的比较中,您正在比较字符串,而不是日期。在SQL string comparison is done based on alphabetical order。在您的示例中,这意味着'28...' > '24...'

你应该

作为旁注,包括工作日在内,没有必要检查日期范围,所以我建议删除它以避免错误。事实上,你的例子中似乎有一个错误:星期二应该是你问题的星期三。

答案 4 :(得分:0)

希望您可以修复您的数据......但根据您的示例日期,这里是一个CTE,它将修复您的日期并格式化您的数据,以便进行过滤。

WITH [SubDates] AS (
    SELECT 
        [FILES].*
        ,SUBSTRING([FILES].[RECORDDATE], 0, PATINDEX('%20[0-9][0-9] %', [FILES].[RECORDDATE]) + 4) AS [RECORDDATE_Sub]
    FROM [FILES]
), [AsDates] AS (
    SELECT 
        [SubDates].*
        ,CASE ISDATE([SubDates].[RECORDDATE_Sub])
            WHEN 1 THEN CONVERT(DATE, [SubDates].[RECORDDATE_Sub])
            END AS [RECORDDATE_Fixed]
    FROM [SubDates]
)
SELECT * 
FROM [AsDates] 
WHERE 
    [AsDates].[RECORDDATE_Fixed] BETWEEN '11 January 2015' AND '24 October 2015'

答案 5 :(得分:-1)

试试这个

select * from FILES where RECORDDATE between STR_TO_DATE('11 January 2015 Saturday',"%d %M %Y %W") and STR_TO_DATE('24 October 2015 Monday',"%d %M %Y %W")