[英]How to force SQL Server to only allow one insert of record every 3 minutes
我正在使用SQL Server,我需要一種方法來強制我的數據庫只允許在3分鍾內插入一個特定記錄。
例如,如果我插入電話號碼為3053333333的記錄,我需要一種方法強制不再輸入相同的電話號碼,直到3分鍾后。
我需要在數據庫級別執行此操作。 任何幫助將不勝感激。
不完全是你要求的,但它應該是一個足夠好的近似。 這種方法的好處是它易於實現和高效。 無需觸發器。
使用此表達式向表中添加一個int
列,該列將使用默認值自動填充:
datediff(minute,'2001-01-01',getdate())/(3)
此表達式計算自某個參考日期(2001-01-01)以來經過了多少分鍾(除以3)。
然后在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)
編輯以解決弗拉基米爾的評論如下:
我將使用PhoneNumber作為鍵的第二個表來跟蹤最近的記錄。
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表中插入電話號碼。
插入時在記錄上存儲時間戳。
在每個插入時,檢查當前時間與同一電話的最后一個時間戳是否至少為3分鍾。
如果您通過存儲過程進行插入,請在那里執行檢查。 否則,您必須在觸發器中執行此操作
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.