伙计我有一个存储过程,只有当最后插入的值不同时,才会在表中插入一个新值。
CREATE PROCEDURE [dbo].[PutData]
@date datetime,
@value float
AS
IF NOT EXISTS(SELECT * FROM Sensor1 WHERE SensorTime <= @date AND SensorTime = (SELECT MAX(SensorTime) FROM Sensor1) AND SensorValue = @value)
INSERT INTO Sensor1 (SensorTime, SensorValue) VALUES (@date, @value)
RETURN 0
现在,由于我是以高频率(比如每10毫秒)执行此操作,IF NOT EXISTS (SELECT)
语句通常会获取旧数据,因此我得到重复数据。是否可以在存储过程中锁定整个表,以确保SELECT
语句始终接收最新数据?
答案 0 :(得分:0)
根据海报对问题的评论,c#代码从传感器接收值。代码只有在与前一个值不同时才会插入值。
为什么不在代码中存储插入的最后一个值,而只是在新值不同的情况下调用该过程?然后程序不需要检查数据库中是否存在该值;它可以简单地插入。这会更有效率。
答案 1 :(得分:0)
你可以这样写:
CREATE PROCEDURE [dbo].[PutData]
@date datetime,
@value float
AS
BEGIN TRANSACTION
INSERT INTO Sensor1 (SensorTime, SensorValue)
SELECT SensorTime = @date,
SensorValue = @value
WHERE NOT EXISTS(SELECT *
FROM Sensor1 WITH (UPDLOCK, HOLDLOCK)
WHERE SensorValue = @value
AND SensorTime <= @date
AND SensorTime = (SELECT MAX(SensorTime) FROM Sensor1) )
COMMIT TRANSACTION
RETURN 0
稍微思考一下,你也可以这样写:
CREATE PROCEDURE [dbo].[PutData]
@date datetime,
@value float
AS
BEGIN TRANSACTION
INSERT INTO Sensor1 (SensorTime, SensorValue)
SELECT SensorTime = @date,
SensorValue = @value
FROM (SELECT TOP 1 SensorValue, SensorTime
FROM Sensor1 WITH (UPDLOCK, HOLDLOCK)
ORDER BY SensorTime DESC) last_value
WHERE last_value.SensorTime <= @date
AND last_value.SensorValue <> @value
COMMIT TRANSACTION
RETURN 0
假设您在SensorTime上有一个唯一索引(PK?),实际上这应该非常快。