здесь вы можете сохранить каждую часть даты, и при этом ограничить их действительной датой:
CREATE Table PartialDates
(
YearPart smallint --(2 bytes -32k to +32k)
,MonthPart tinyint --(1 byte 0 to 255)
,DayPart tinyint --(1 byte 0 to 255)
,CompleteDate AS (CONVERT(datetime,CONVERT(varchar(10),YearPart)+'-'+CONVERT(varchar(10),MonthPart)+'-'+CONVERT(varchar(10),coalesce(DayPart,1))))
)
ALTER TABLE dbo.PartialDates ADD CONSTRAINT
CK_PartialDates_IsDate CHECK (ISDATE(CONVERT(varchar(10),YearPart)+'-'+CONVERT(varchar(10),MonthPart)+'-'+CONVERT(varchar(10),coalesce(DayPart,1)))=1)
GO
insert into PartialDates (yearpart,monthpart,daypart) values(2009,91,1) --error
insert into PartialDates (yearpart,monthpart,daypart) values(2009,1,1) --ok
insert into PartialDates (yearpart,monthpart,daypart) values(2009,1,51) --error
insert into PartialDates (yearpart,monthpart,daypart) values(2009,2,29) --error
insert into PartialDates (yearpart,monthpart,daypart) values(2009,2,28) --ok
insert into PartialDates (yearpart,monthpart,daypart) values(2009,2,null)--ok
select * from PartialDates
YearPart MonthPart DayPart CompleteDate
-------- --------- ------- -----------------------
2009 1 1 2009-01-01 00:00:00.000
2009 2 28 2009-02-28 00:00:00.000
2009 2 NULL 2009-02-01 00:00:00.000
(3 row(s) affected