【问题标题】:How to pass the Datetime value as parameter to a stored procedure?如何将日期时间值作为参数传递给存储过程?
【发布时间】:2012-01-01 17:46:27
【问题描述】:

在表中,我有一个名为BillDate (Datetime) 的列。日期时间以YYYY-MM-DD 格式存储(例如:2012-01-01 00:00:00.000)。现在我想检索日期时间值范围之间的值。当我使用以下查询时,我无法得到结果:

SELECT * FROM RequestHeader
WHERE 
  CONVERT(VARCHAR, RH.BillDate ,105) BETWEEN CONVERT(VARCHAR, @FromDate,105) 
  AND CONVERT(VARCHAR,@ToDate , 105)

@FromDate is passed as : '2012-01-01'
@ToDate is passed as : '2012-01-01'

【问题讨论】:

  • 表格列和参数不使用convert会怎样?
  • "日期时间以 YYYY-MM-DD 格式存储" - 不,不是。它存储为DateTime,无论其内部表示是什么。不要将格式化与存储混淆。
  • 你为什么传入字符串参数而不是DateTime
  • 谢谢。如果我删除转换功能,它确实很好用。但是当日期时间作为 '2012-01-01 08:09:00.000' 存储在列中时呢?
  • SQL Server 中的 DateTime 不存储在任何 STRING FORMAT 中 - 它是一个 DateTime,它存储为 8 个二进制字节。它应用了 NO FORMATTING - NONE

标签: sql-server datetime


【解决方案1】:

试试这个:

SELECT * FROM RequestHeader
WHERE 
  CONVERT(VARCHAR, RH.BillDate ,105) BETWEEN CONVERT(VARCHAR, CAST(@FromDate AS DATETIME),105) 
  AND CONVERT(VARCHAR, CAST(@ToDate AS DATETIME), 105)

不幸的是,使用此方法不使用索引,因此如果您希望在日期列被索引的情况下能够快速执行查询,您将不会在这里感受到它。

【讨论】:

    【解决方案2】:

    解决此问题的最佳方法是将日期时间值作为日期时间值而不是字符串传递。这对于 SQL 服务器和存储过程源代码的读者来说都会更容易。

    【讨论】:

      【解决方案3】:

      您需要使用 121 格式的代码而不是 105,如下所示:

       SELECT * FROM RequestHeader
      WHERE 
        CONVERT(VARCHAR, RH.BillDate ,121) BETWEEN CONVERT(VARCHAR, @FromDate,121) 
        AND CONVERT(VARCHAR,@ToDate , 121)
      

      BUT如果存储为DATETIME类型,则无需使用CONVERT,此时优化器可以使用索引:

      SELECT * FROM RequestHeader
      WHERE 
        RH.BillDate BETWEEN @FromDate AND @ToDate
      

      【讨论】:

        【解决方案4】:

        在您的示例中,@FromDate 与@ToDate 相同。两个等效值之间没有值。我将假设您将这些值仅作为示例,因此无论如何我都会尝试回答。

        首先,我认为不需要将 BillDate 转换为 VARCHAR。如果传递的参数也是日期,则也没有理由转换它们。如果不是,可以转换。

        我创建了一个简单的测试来确认我的假设:

        DECLARE @FromDate VARCHAR(50)
        DECLARE @ToDate VARCHAR(50)
        
        SET @FromDate = '2012-01-01'
        SET @ToDate = '2012-01-05'
        
        
        INSERT INTO RequestHeader (BillDate) VALUES('12/1/2011')
        INSERT INTO RequestHeader (BillDate) VALUES('1/3/2012')
        INSERT INTO RequestHeader (BillDate) VALUES('1/4/2012')
        INSERT INTO RequestHeader (BillDate) VALUES('1/5/2012')
        
        SELECT * FROM RequestHeader
        WHERE
            BillDate BETWEEN CAST(@FromDate AS DateTime) AND CAST(@ToDate AS DateTime)
        

        结果:

        BillDate
        2012-01-03 00:00:00.000
        2012-01-04 00:00:00.000
        2012-01-05 00:00:00.000
        
        (3 row(s) affected)
        

        【讨论】:

          【解决方案5】:

          尽量简单

          SELECT * FROM RequestHeader
          WHERE 
            BillDate BETWEEN @FromDate AND @ToDate
          

          @FromDate 和 @ToDate 当然是日期时间变量,而不是 varchars。

          【讨论】:

            【解决方案6】:
            SELECT * FROM RequestHeader
            WHERE BillDate 
            BETWEEN convert(Datetime,@FromDate,102) 
            AND convert(Datetime,@ToDate,102)
            

            【讨论】:

              【解决方案7】:

              标题和问题涉及不同的概念。标题提到“存储过程”,问题和答案是直接从一个表中选择的。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-09-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多