我正在使用SQL Server,我需要一种方法来强制我的数据库只允许在3分钟内插入某个记录。
例如,如果我插入电话号码为3053333333的记录,我需要一种方法在3分钟后再强制输入同一电话号码。
我需要在数据库级别执行此操作。任何帮助将不胜感激。
答案 0 :(得分:2)
不完全是你要求的,但它应该是一个足够好的近似值。 这种方法的好处是它易于实现和高效。无需触发器。
使用此表达式向表中添加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
之后才会接受下一行。
答案 1 :(得分:1)
如果在过去三分钟内还没有记录,请插入。
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表中插入电话号码。
答案 2 :(得分:0)
在插入时在记录上存储时间戳。
在每次插入时,检查当前时间与同一手机的最后一个时间戳是否至少为3分钟。
如果您通过存储过程进行插入,请在那里执行检查。否则,您必须在触发器中执行此操作