【问题标题】:compare two datetime by Date and Time in dynamic query在动态查询中按日期和时间比较两个日期时间
【发布时间】:2012-04-24 22:54:49
【问题描述】:

我正在尝试比较两个日期时间,但它在动态查询中不起作用。 为什么部分时间不起作用? 我的代码是这些

    ALTER PROCEDURE [dbo].[testdate]    
    @startDate datetime = null  ,
    @endDate datetime = null,
    @TableName nvarchar(100) ,
    @SearchString NVARCHAR(200)
AS
BEGIN   
    SET NOCOUNT ON; 
    declare @sqlcmd nvarchar(max)


    set  @sqlcmd= 'select * from '+@TableName  +' where '   
    if @startDate is not null and @endDate is not null
    begin

        /*set @sqlcmd=@sqlcmd + ' ( DateLog between'''
        + convert (nvarchar(50), @startDate, 101)
        +''' and ''' 
        --+ convert (nvarchar(50),DATEADD(D,1, @endDate), 101)
        + convert (nvarchar(50), @endDate, 101)
        + ''' ) and '   
        */
        set @sqlcmd=@sqlcmd + ' ( DateLog between @startDate and @endDate ) and '

    end     


    set @sqlcmd=@sqlcmd + '('
    SELECT 
            @sqlcmd  = @sqlcmd + '  [' + SYSCOLUMNS.NAME + '] LIKE N''%'+@SearchString+'%'' or '    
            FROM SYSCOLUMNS 
            WHERE OBJECT_NAME(id) =  @TableName AND TYPE_NAME(SYSCOLUMNS.XTYPE) IN ('VARCHAR','NVARCHAR','CHAR','NCHAR','INT','DECIMAL')

        set @sqlcmd  = @sqlcmd  + '1<>1)'                           
    --print @sqlcmd                                             
    Exec(@sqlcmd)
END

我的表 AccountLog 有这些字段和数据

     UserName     DateLog
     Salah        2012-04-06 22:06:19.493
     John         2012-08-06 22:06:22.800

这个查询是真的

 select * from AccountLog where DateLog between '2012-04-06T22:06:19' and '2012-08-06T22:06:23'

但是这个查询没有给我合适的结果

declare @a datetime
declare @b datetime 
set @a = '2012-04-06T22:06:19'  
set @b = '2012-08-06T22:06:23'
exec testdate @a,@b,'AccountLog',N'test' 

【问题讨论】:

  • 为什么是 2012-04-06T22:06:19 而不是 2012-04-06 22:06:19 ?
  • 因为时间部分,如果我不使用 -(dash) 这不是真的
  • 为什么要使用动态 SQL?
  • 你能打印一下@sql,看看能给你带来什么吗?
  • 因为表太多了。我有另一个字段 TableName 是输入参数

标签: sql-server-2008 tsql datetime compare


【解决方案1】:

您应该使用强类型参数并完全抛弃任何这种转换为 nvarchar 的废话。

EDIT更新了更多的需求变化。

ALTER PROCEDURE [dbo].[testdate]    
  @startDate    DATETIME = NULL,
  @endDate      DATETIME = NULL,
  @TableName    NVARCHAR(100),
  @SearchString NVARCHAR(200)
AS
BEGIN 
  SET NOCOUNT ON;

  DECLARE @sql NVARCHAR(MAX);
  SET @sql = N'SELECT * FROM dbo.' + QUOTENAME(@TableName) 
    + ' WHERE (1 = 0 ';

  SELECT @sql = @sql + ' OR ' + QUOTENAME(name) + ' LIKE N''%'+@SearchString+'%'''  
    FROM sys.columns WHERE [object_id] = OBJECT_ID('dbo.' + @TableName)
    AND system_type_id IN (56,106,167,175,231,239);

  SET @sql = @sql + ')';

  IF @startDate IS NOT NULL AND @endDate IS NOT NULL
  BEGIN
    SET @sql = @sql + ' AND DateLog BETWEEN @s AND @e';
  END

  EXEC sp_executesql @sql, N'@s DATETIME, @e DATETIME', @startDate, @endDate;
END
GO

【讨论】:

  • Aaron Bertrand 你的代码不正确你的代码有这个错误必须声明标量变量“@startDate”。
  • @SalahSanjabian 你能说得更具体一点吗?
  • 您还想了解什么?我的代码很清楚我只是日期时间有问题
  • 您最初的评论没有包含实际的错误消息。如果您准确地复制了代码(不仅仅是其中的一部分),您就不应该收到该错误消息。
  • 太好了,谢谢。下次我可能对您的一个问题提出意见时,请提醒我这一点。 :-(
【解决方案2】:

您将日期和时间传递到您的过程中,但是当您将它们转换为动态 SQL 时,您使用的是格式 101,它删除了时间部分。尝试将 101 更改为 126(您的代码中有 2 个地方使用了 101,请确保同时更改它们。

【讨论】:

    猜你喜欢
    • 2020-01-14
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多