2009-09-01 10 views
3

私はMS SQL Server 2005を使用しており、部分的に日付値を格納する必要があります。例えば、日付の日の部分は、実際には不明のままであるかもしれませんが、MS SQL Serverは、フォローのような完全な日付を指定する制約:日付の値を部分的に保存するにはどうすればいいですか?

INSERT foo(dt) VALUES('2001-10-31'); 

は、私もこのようなものを使用したいと思います:

INSERT foo(dt) VALUES ('2001-10-??'); 

SET NOCOUNT ON 
CREATE TABLE foo ( 
    dt INT 
) 
INSERT foo VALUES ( 
    DATEPART(YEAR, GETDATE()) * 10000 
     + DATEPART(MONTH, GETDATE()) * 100 
     + DATEPART(DAY, GETDATE()) 
) 
SELECT dt FROM foo 
DROP TABLE foo 

... HM、私はそれが唯一の方法だかどうかを信じることができません:もちろん

は、MS SQLは、このような日付を受け入れることができない、と私は乗算に日付部分を変換ラフの例を見つけましたゾルにこの問題を解決するにはどうすればよいですか?

ありがとうございます。


UPD 2014:
はまたStoring partial dates in a database

+0

なぜあなたは完全な日付を知りませんか?完全な日付がない日付フィールドはどのように使用されますか? – HLGEM

+0

時々ある日の日の部分は本当に不明です。例えば、未発表の音楽デモレコードはまばらに書き込むことができますが、そのレコードは、レコードの日を示すものではなく、誤っているか部分的に日付が付いている可能性があります。だから私は記録情報の記入を延期する可能性を予約したいと思います。 –

答えて

2

は、各日付の一部を格納し、まだ有効な日付にそれらを制約することができます

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 
+0

ありがとう、KM、私はあなたの解決策を検討します –

1

スマート日付キーを参照してくださいは間違いなく行く方法です。

select cast(convert(varchar, GETDATE(), 112) as int) 

あなたはconvertこのストレートintに、それが動作しないことができると思うだろう:SQL Serverがconvertを使用して、それを得るための簡単な方法を提供し、あなたのコードは、しかし、少し長いです。したがって、varcharに変換してからintに変換する必要があります。

あなたはそれが実際の日の代わりに、その日のために00になりたい場合は、次の

select cast(convert(varchar, getdate(), 112) as int) - day(getdate()) 

うまくいけば、このことができます!

+0

返事ありがとう、Eric。私は現在のあなたのアドバイスをよく見ています –

2

月、日、年を別々の列に格納することを検討しましたか?それは非常に手ほどきではありません&単純なアプローチですが、時にはそれが行く方法です。これにより、コードの作業が必要になる可能性のある他の人の混乱を混乱させる可能性のある型変換を行わずに、特定の月および/または日の値を簡単に照会することができます。ここ

+1

私は通常これをお勧めしませんが、あなたがその日を知らないなら、恐ろしい操作なしにそれを行う方法を見ません。また、3つのフィールドのいずれかが変更された場合、および3つのフィールドがすべて有効な日付を構成する場合にのみ、トリガーから移入する実日付フィールドを追加することもできます。有効な日付がある場合は、必要に応じて 日付機能を使用してクエリできます。 – HLGEM

関連する問題