簡體   English   中英

如何強制SQL Server每3分鍾只允許一次記錄插入

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM