Sql server 如何将Datetime值作为参数传递给存储过程?

Sql server 如何将Datetime值作为参数传递给存储过程?,sql-server,datetime,Sql Server,Datetime,在表中,我有一个名为BillDate(Datetime)的列。日期时间以YYYY-MM-DD格式存储(例如:2012-01-01 00:00:00.000)。现在我想检索datetime值范围之间的值。当我按以下方式使用查询时,我无法获得结果: SELECT * FROM RequestHeader WHERE CONVERT(VARCHAR, RH.BillDate ,105) BETWEEN CONVERT(VARCHAR, @FromDate,105) AND CONVERT(

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

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

试试这个:

从RequestHeader中选择*
哪里
转换(VARCHAR,RH.BillDate,105)之间的转换(VARCHAR,CAST(@FromDate作为DATETIME),105)
和转换(VARCHAR,CAST(@todateas DATETIME),105)

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

您需要使用121格式代码intead of 105,如下所示:

 SELECT * FROM RequestHeader
WHERE 
  CONVERT(VARCHAR, RH.BillDate ,121) BETWEEN CONVERT(VARCHAR, @FromDate,121) 
  AND CONVERT(VARCHAR,@ToDate , 121)
但是如果它存储为DATETIME类型,则不需要使用CONVERT,在这种情况下,优化器可以使用索引:

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

解决此问题的最佳方法是将日期时间值作为日期时间值传递,而不是作为字符串传递。这在SQL server和存储过程源代码的读取器上都比较容易。

在您的示例中,@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)

让它尽可能简单

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

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

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

如果不在表列和参数上使用转换,会发生什么情况?“日期时间以YYYY-MM-DD格式存储”-不,不是。它存储为
日期时间
,无论其内部表示形式是什么。不要混淆格式和存储。为什么要传入字符串参数而不是
DateTime
?谢谢。如果我删除convert函数,效果会很好。但是,当datetime作为'2012-01-01 08:09:00.000'存储在列中时,该怎么办?
datetime
在SQL Server中不是以任何字符串格式存储的-它是一个
datetime
,存储为8个二进制字节。它没有应用任何格式-无。
SELECT * FROM RequestHeader
WHERE BillDate 
BETWEEN convert(Datetime,@FromDate,102) 
AND convert(Datetime,@ToDate,102)
SELECT * FROM RequestHeader
WHERE BillDate 
BETWEEN convert(Datetime,@FromDate,102) 
AND convert(Datetime,@ToDate,102)