我有一个T-SQL存储过程,我想搜索一个特定的值,并且可选地将搜索限制在特定日期(如果它们被传入)。如果为这些日期中的任何一个传递空值,那么我想要忽略那些。我想通过将输入日期设置为最小值或最大值(如果它们为空)来实现此目的的方式。我不想硬编码最小值和最大值。所以我想知道C#DateTime.MaxValue
和DateTime.MinValue
的SQL等价物是什么。
我正在考虑像这样使用Coalesce
SELECT EmployeeName FROM Employee
WHERE EmployeeID = @EmployeeId AND
Birthday BETWEEN Coalesce(@StartDate, <MinDateTime>) AND
Coalesce(@EndDate, <MaxDateTime>)
我可以使用内置函数/常量/变量/枚举用于<MinDateTime>
和<MaxDateTime>
变量吗?
有什么建议吗?
答案 0 :(得分:11)
SQL Server中没有这样的功能。您可以轻松找到BOL允许的min and max dates(1753-01-01 - 9999-12-31)。或者您可以轻松地对另一个日期进行硬编码(如果您真的正在使用生日,1800-01-01 - 2100-12-31可能就足够了)。或者你可以(如果它是你展示的范围查询),让合并回到生日本身:
SELECT EmployeeName FROM Employee
WHERE EmployeeID = @EmployeeId AND
Birthday BETWEEN Coalesce(@StartDate, Birthday) AND
Coalesce(@EndDate, Birthday)
但请注意,对于非常大的表格,这不一定能很好地扩展。
接受后编辑,回复OP的评论
通常,对于SQL,如果您经常需要“引用”数据,请自行将其添加为表格。 (谷歌的“日历表”或“数字表sql”)。所以在这种情况下,如果你想,你可以添加一个“常量”(或者可能是“限制”表):
create table Constants (
Lock char(1) not null,
datetimeMin datetime not null,
datetimeMax datetime not null,
intMin int not null,
intMax int not null,
/* Other Min/Max columns, as required */
constraint PK_Constants PRIMARY KEY (Lock),
constraint CK_Constants_Locked CHECK (Lock='X')
)
insert into Constants (Lock,datetimeMin,datetimeMax,intMin,intMax)
select 'X','17530101','99991231',-2147483648,2147483647
然后您可以在查询中引用(通过子选择,或通过交叉连接到此表)。 E.g。
SELECT EmployeeName
FROM Employee, Constants
WHERE EmployeeID = @EmployeeId AND
Birthday BETWEEN Coalesce(@StartDate, Constants.datetimeMin) AND
Coalesce(@EndDate, Constants.datetimeMax)
(Lock,Primary Key和Check约束,协同工作以确保此表中只存在一行)
答案 1 :(得分:4)
对于SQL Server,根据BOL,限制为:
datetime
:1753-01-01 00:00:00至9999-12-31 23:59:59.997 smalldatetime
:1900-01-01 00:00:00至2079-06-06 23:59:29.998 date
:0001-01-01至9999-12-31 datetime2
:0001-01-01 00:00:00至9999-12-31 23:59:59.9999999 如您所见,这取决于您的确切数据类型。
至于查询,我会这样做:
SELECT EmployeeName
FROM Employee
WHERE EmployeeID = @EmployeeId
AND (@StartDate IS NULL
OR Birthday >= @StartDate)
AND (@EndDate IS NULL
OR Birthday <= @EndDate)
答案 2 :(得分:3)
没有内置函数来获取最小或最大日期时间值。您必须对值进行硬编码或从数据库中检索值。
如果参数为NULL
,您只需选择最小值和最小值即可。最大日期来自Employee
表格。
IF (@StartDate IS Null)
BEGIN
SELECT @StartDate = MIN(Birthday) FROM Employee
END
IF (@EndDate IS Null)
BEGIN
SELECT @EndDate = MAX(Birthday) FROM Employee
END
SELECT EmployeeName FROM Employee
WHERE EmployeeID = @EmployeeId AND
Birthday BETWEEN @StartDate AND @EndDate