Sql-Server-2005

SQL Server 2005 - 將日期時間欄位約束為日期的最佳方法

  • January 10, 2018

然而:

從 SQL Server 2008 開始的日期欄位類型

給定一張桌子:

CREATE TABLE dbo.MyTable
(
   Code int NOT NULL,
   DateCode datetime NOT NULL
)
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED 
(
[Code] ASC, [DateCode] DESC
);

約束 DateCode 只是一個日期的最佳方法是什麼?

它必須允許沒有時間部分的日期。

2017-01-02
2017-01-02 00:00:00.000
20170102

現在我正在使用:

ALTER TABLE dbo.MyTable ADD CONSTRAINT [CHK_MyTable_DateCode]
   CHECK ([DateCode] = DATEADD(DAY, 0, DATEDIFF(DAY, 0, [DateCode])));

但是,我想知道是否有最好/最短的方法來完成它。

您可以稍微簡化一下,因為 SQL Server 知道datetime它可以將該值視為自 0 以來的天數。我更喜歡使用'19000101'大於零的值,因為發生的事情稍微不那麼神秘:

ALTER TABLE dbo.MyTable
ADD CONSTRAINT CHK_MyTable_DateCode
CHECK (DateCode = DATEDIFF(DAY, '19000101', DateCode));

但是,我發現責罵那些可能使用他們沒有意識到包含時間組件的內置GETDATE()函式或參數的使用者是一個奇怪的選擇。@OrderDate因此,解決此問題的一種更簡潔的方法是使用觸發器:

CREATE TRIGGER dbo.MyTable_RoundCodeDate
ON dbo.MyTable
INSTEAD OF INSERT
AS
BEGIN
 SET NOCOUNT ON;
 INSERT dbo.MyTable(Code, DateCode)
   SELECT Code, DATEDIFF(DAY, '19000101', DateCode)
   FROM inserted;
END
GO

這裡的一些人不喜歡使用INSTEAD OF觸發器,但我認為在插入之前按摩這些值比在插入之後更好。PK 的處理方式與沒有觸發器的情況相同 - 仍然會在插入時擷取違規(但是,使用後觸發器,您不會在觸發器程式碼執行之前遇到違規,理論上這至少意味著更多的日誌記錄)。實際上,您可以GROUP BY在觸發器中添加一個以靜默忽略源語句中的重複項,例如INSERT ... VALUES(1,GETDATE()), (1,CURRENT_TIMESTAMP);.

引用自:https://dba.stackexchange.com/questions/164678