I have a T-SQL stored procedure where I want to search for a particular value and optionally limit the search to particular dates if they are passed in. If null values are passed in for either of these dates, then I want to ignore those. The way I am thinking of doing this by setting the input dates to minimum or maximum if they are null. I would prefer not to hardcode the minimum and maximum values though. So I am wondering what the SQL equivalent of the C# DateTime.MaxValue
and DateTime.MinValue
are.
I am thinking of using Coalesce like so
SELECT EmployeeName FROM Employee
WHERE EmployeeID = @EmployeeId AND
Birthday BETWEEN Coalesce(@StartDate, <MinDateTime>) AND
Coalesce(@EndDate, <MaxDateTime>)
Is there a built in function/constant/variable/enum I can use for the <MinDateTime>
and <MaxDateTime>
variables?
Any suggestions?
There's no such functionality in SQL Server. You can easily find the min and max dates allowed in BOL (1753-01-01 - 9999-12-31). Or you could hard code another date easily (if you really are working with birthdays, 1800-01-01 - 2100-12-31 would probably suffice). Or you could (if it is the range query you've shown), have the coalesce fall back to the birthday itself:
SELECT EmployeeName FROM Employee
WHERE EmployeeID = @EmployeeId AND
Birthday BETWEEN Coalesce(@StartDate, Birthday) AND
Coalesce(@EndDate, Birthday)
But note that this will not necessarily scale well for very large tables.
Edited after accept, to respond to comment from OP
Generally, for SQL, if you're needing "reference" data frequently, you add it as a table yourself. (Google for "calendar table" or "number table sql"). So in this instance, if you wanted to, you could add a "constants" (or maybe "limits" table):
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
Which you could then reference in queries (either through a subselect, or by cross joining to this table). E.g.
SELECT EmployeeName
FROM Employee, Constants
WHERE EmployeeID = @EmployeeId AND
Birthday BETWEEN Coalesce(@StartDate, Constants.datetimeMin) AND
Coalesce(@EndDate, Constants.datetimeMax)
(The Lock, Primary Key, and Check constraint, work together to ensure that only a single row will ever exist in this table)
For SQL Server specifically, according to BOL, the limits are:
datetime
: 1753-01-01 00:00:00 through 9999-12-31 23:59:59.997smalldatetime
: 1900-01-01 00:00:00 through 2079-06-06 23:59:29.998date
: 0001-01-01 through 9999-12-31datetime2
: 0001-01-01 00:00:00 through 9999-12-31 23:59:59.9999999As you can see, it depends on your exact data type.
As for the query, I would do it like this:
SELECT EmployeeName
FROM Employee
WHERE EmployeeID = @EmployeeId
AND (@StartDate IS NULL
OR Birthday >= @StartDate)
AND (@EndDate IS NULL
OR Birthday <= @EndDate)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With