TSQL - 查看日期是否在日期

时间:2015-05-07 12:58:20

标签: sql tsql datetime

我使用以下动态SQL查询来过滤数据范围的结果。如果我的“createdFrom”和“createdTo”日期不为null,我会在select语句中添加where子句。

我有两个问题:

  1. 你会怎么做呢?我的逻辑是否正确?

  2. 我在添加以下代码时收到错误消息,为什么我会收到此消息?:

      

    将字符串转换为smalldatetime时转换失败   数据类型。

  3. Declare @createdFromDate SMALLDATETIME = NULL ,
            @createdToDate SMALLDATETIME = NULL 
    
     IF @createdFromDate IS NOT NULL 
        BEGIN
           SELECT @sWhere = @sWhere + 'AND g.CreatedOn > '+@createdFromDate
        END
     IF @createdToDate IS NOT NULL
        BEGIN
           SELECT @sWhere = @sWhere + ' AND g.CreatedOn <'+@createdToDate
        END
    

3 个答案:

答案 0 :(得分:2)

对于你的问题

  

当我添加以下代码时,我当前收到错误消息,为什么我会收到此消息?

您收到此错误的原因是执行查询时您的条件变为

AND g.CreatedOn > 2015-05-07

哪个无效,而是你的需要

AND g.CreatedOn > '2015-05-07'

因此你的SQL应该是

SELECT @sWhere = @sWhere + 'AND g.CreatedOn > '''+@createdFromDate + ''''

对于你的问题

  

你会怎么做呢?我的逻辑是否正确?

您应该使用sp_executesql并在动态SQL中传递变量。

IF @createdFromDate IS NOT NULL 
   BEGIN
      SELECT @sWhere = @sWhere + 'AND g.CreatedOn > @createdFromDate'
   END

IF @createdToDate IS NOT NULL
   BEGIN
      SELECT @sWhere = @sWhere + ' AND g.CreatedOn < @createdToDate'
   END

而不是

EXEC(@SQL)

你会用

EXEC sp_executeSQL @SQL,N'@createdFromDate smalldatetime,@createdToDate smalldatetime',@createdFromDate,@createdToDate

@SQL

构建@Where的位置

注意:如果这是使用它的唯一原因,您就不需要动态SQL。

答案 1 :(得分:2)

您问题的直接答案是日期常量需要用单引号括起来。而不是:

SELECT @sWhere = @sWhere + 'AND g.CreatedOn > '+@createdFromDate

使用:

SELECT @sWhere = @sWhere + 'AND g.CreatedOn > ''' + @createdFromDate + ''''

您的问题的正确答案是您应该使用sp_executesql来执行动态SQL。这允许您包含参数,因此您可以说:

exec sp_executesql @sql,
    N'@createdFromDate date',
    @createdFromDate = @createdFromDate;

其中@sql是一个看起来像的字符串:

select . . .
. . .
where . . . and
      g.CreatedOn = @createdFromDate;

答案 2 :(得分:2)

导致问题的原因是您尝试将smalldatetimeVARCHAR等字符串数据类型连接起来。您可以将日期转换为VARCHAR来绕过它。 CONCAT()会更好。在连接不同数据类型的值时,它是您最好的朋友。我强烈建议使用它,遗憾的是它只是SQL Server 2012及以上版本的支持,并且很少有人知道它甚至存在。

现在针对您的具体问题,我认为不需要动态SQL。您通常应该尽量避免使用动态SQL,因为以后很难调试和进行更改。像这样的东西对你来说会很好。

Declare @createdFromDate SMALLDATETIME = NULL,
        @createdToDate SMALLDATETIME = NULL 

SELECT *
FROM yourTable
WHERE   (
            date_column > @createdFromDate
            OR @createdFromDate IS NULL
        )
        AND
        (
            date_column < @createdToDate
            OR @createdToDate IS NULL
        )