我正在使用SQL Server,我需要一種方法來強制我的數據庫在3分鐘內只允許一個特定記錄的插入。如何強制SQL Server只允許每3分鐘插入一條記錄
例如,如果我插入一個電話號碼爲3053333333的記錄,我需要一種方法來強制3分鐘後不再輸入相同的電話號碼。
我需要在數據庫級別執行此操作。任何幫助將不勝感激。
我正在使用SQL Server,我需要一種方法來強制我的數據庫在3分鐘內只允許一個特定記錄的插入。如何強制SQL Server只允許每3分鐘插入一條記錄
例如,如果我插入一個電話號碼爲3053333333的記錄,我需要一種方法來強制3分鐘後不再輸入相同的電話號碼。
我需要在數據庫級別執行此操作。任何幫助將不勝感激。
插入時在記錄上存儲時間戳。
在每次插入時,檢查當前時間與同一電話號碼的最後一次時間戳是否至少3分鐘。
如果您正在通過存儲過程進行插入,請在那裏執行檢查。否則你將不得不這樣做在觸發器
不完全是你要求的,但它應該是一個足夠好的近似值。 這種方法的好處是易於實現並且高效。不需要觸發器。
添加int
列將被用默認值使用此表達式自動填充該表:
datediff(minute,'2001-01-01',getdate())/(3)
該表達式計算,因爲一些參考日期多少分鐘(除以3)已經過去(2001 -01-01)。
然後在PhoneNumber
和這個PhoneTimestamp
列上添加唯一索引。
CREATE TABLE [dbo].[TestTable](
[ID] [int] IDENTITY(1,1) NOT NULL,
[PhoneNumber] [varchar](50) NOT NULL,
[PhoneTimestamp] [int] NOT NULL CONSTRAINT [DF_TestTable_PhoneTimestamp]
DEFAULT (datediff(minute,'2001-01-01',getdate())/(3)),
CONSTRAINT [PK_TestTable] PRIMARY KEY CLUSTERED
(
[ID] ASC
))
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_PhoneNumber] ON [dbo].[TestTable]
(
[PhoneNumber] ASC,
[PhoneTimestamp] ASC
)
GO
插入值表中不設置PhoneTimestamp
明確,讓默認表情工作:
INSERT INTO [dbo].[TestTable] ([PhoneNumber]) VALUES
('124');
第一INSERT
將正常工作,但如果你試圖在同一3再次運行 - 分爲「時隙」它將失敗與消息:
Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.TestTable' with unique index
'IX_PhoneNumber'. The duplicate key value is (124, 2649888).
The statement has been terminated.
它是一個近似值,因爲你可以插入小於3分鐘的間隔兩行。如果插入第一行,例如,在10:02:58
,第二行插入10:03:02
,它將被接受。但是,如果您在10:03:02
處插入一行,則只有在10:06:00
之後纔會接受下一行。
只要在最近三分鐘內沒有記錄就插入。
DECLARE @ThreeMinutesAgo datetime2 =
DATEDIFF(minute, -3, getdate())
IF NOT EXISTS (
SELECT * FROM PhoneRecords
WHERE PhoneNumber = @PhoneNumber
AND TimeStamp > @ThreeMinutesAgo)
INSERT INTO PhoneRecords
(PhoneNumber, TimeStamp, MoreStuff)
VALUES
(@PhoneNumber, getdate(), @MoreStuff)
編輯解決以下弗拉基米爾的評論:
我會去這個使用第二表******中國作爲重點,跟蹤最新記錄。
CREATE TABLE PhoneNumbers (
PhoneNumber varchar(50) NOT NULL PRIMARY KEY,
LastTimeStamp datetime2
)
PhoneNumber將是PhoneRecords表中的外鍵。要添加一個新的記錄:
DECLARE @Timestamp datetime2 = getdate()
DECLARE @ThreeMinutesAgo datetime2 =
DATEDIFF(minute, -3, @Timestamp)
UPDATE PhoneNumbers
SET LastTimeStamp = @TimeStamp
WHERE PhoneNumber = @PhoneNumber AND LastTimeStamp < @ThreeMinutesAgo
,只有當時間戳在3分鐘內舊的工作 - 並且注意,如果另一個進程正在更新記錄,我必須等待它被解鎖試試我的更新。所以,如果我做了更新,
IF @@ROWCOUNT = 1
INSERT INTO PhoneRecords
(PhoneNumber, TimeStamp, MoreStuff)
VALUES
(@PhoneNumber, @Timestamp, @MoreStuff)
你會希望把他們在一個事務,還要檢查需要插入在PHONENUMBERS表中的第一次的電話號碼。
當多次嘗試同時插入相同的值時,如何使它可靠地工作?我提到OP在這個問題的評論中所寫的關切。 –
在上面添加了一個編輯來解決這個問題@VladimirBaranov – RocketCity
@VladimirBaranov:我喜歡你的方法,結果非常簡潔:TRY - 插入 - CATCH - 什麼也不做。 我的問題是,我試圖在預期條件下不使用「CATCH」。有沒有性能方面的考慮?如果這種情況發生的時間不是很少,但是大概會失敗呢?我想知道是否有任何性能損失試圖插入一個壞的外鍵,相比之下首先檢查一個有效的。這可能取決於您嘗試添加不需要的記錄的頻率與有效記錄的頻率。 – RocketCity
難道你不能限制插入是如何完成的嗎? – Carcigenicate
首先想到的是插入觸發器。 –
爲什麼需要在數據庫級別?在數據庫抽象級別很容易做到。 – Eborbob