問題是在具有唯一值約束的列上使用DATEADD函數,同時考慮到新值將與現有值重疊並且實際上會存在違反約束的事實,因爲我們不能有兩個具有相同日期的行。移動X天的T-SQL數據時間列重疊UNIQUE約束
例如我有表[SomeDate]是DateTime類型的表,並且約束是唯一的。我的日期從2017-01-01開始到2018-01-01爲止,並且希望通過爲每個人添加7天來更新記錄。
問題是在具有唯一值約束的列上使用DATEADD函數,同時考慮到新值將與現有值重疊並且實際上會存在違反約束的事實,因爲我們不能有兩個具有相同日期的行。移動X天的T-SQL數據時間列重疊UNIQUE約束
例如我有表[SomeDate]是DateTime類型的表,並且約束是唯一的。我的日期從2017-01-01開始到2018-01-01爲止,並且希望通過爲每個人添加7天來更新記錄。
其中一種可能的方法是將未來日期移出當前的最小 - 最大範圍,然後再考慮我們要添加的天數。這裏是準備好和工作的解決方案:
--Number of days we want to add to existing dates
DECLARE @daysToMoveAhead int = 7;
DECLARE @minDate datetime = (SELECT MIN([SomeDate]) from dbo.MyTable)
DECLARE @maxDate datetime = (SELECT MAX([SomeDate]) from dbo.MyTable)
DECLARE @diff int = DATEDIFF(DAY,@minDate,@maxDate)
--temporary move the dates out of existing min-max range
update dbo.MyTable set [SomeDate] = DATEADD(DAY, @diff,[SomeDate]);
--bring dates back and add as many days as we wanted
update dbo.MyTable set [SomeDate] = DATEADD(DAY, @daysToMoveAhead - @diff,[SomeDate]);
如果您更新所有行,那麼唯一約束應該沒有問題。
下面是一個簡單的例子:
CREATE TABLE T
(
SomeDate date NOT NULL,
CONSTRAINT uc UNIQUE (SomeDate)
)
;WITH CTE AS
(
SELECT CAST(GETDATE() As Date) As TheDate
UNION ALL
SELECT CAST(DateADD(DAY, 1, TheDate) As Date)
FROM CTE
WHERE TheDate < DATEADD(DAY, 10, GETDATE())
)
INSERT INTO T(SomeDate)
SELECT TheDate
FROM CTE
UPDATE T
SET SomeDate = DATEADD(DAY, 3, SomeDate)
我投票關閉這一問題作爲題外話,因爲它屬於上codereview.stackexchange.com。鑑於OP在幾秒鐘內發佈了一個問題和答案,唯一真正的問題可能是如何更好地做到這一點。 – scsimon
當您提出問題時,您可以選擇「回答自己的問題」,以分享您的知識。我這樣做只是爲了向其他人展示如何處理這樣的問題,如果他們有相似的問題。如果有人分享正確的問題答案,尤其是如果我沒有這樣做以獲得「假投票」,我不會看到投票的要點。 –