2014-03-27 46 views
0

伙计们我有一个存储过程,只在最后插入的值不同时在表中插入一个新值。现在锁定整个表存储过程

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 

,因为我在做这个高频率(比如每10ms),该IF NOT EXISTS (SELECT)语句经常变老的数据,正因为如此我得到的重复数据。是否可以在存储过程中锁定整个表,以确保SELECT语句始终接收最新数据?

+0

你能描述你实际上想要做什么吗?我认为问题出在你的设计上。锁定桌面将会产生问题,因为随后对SP的其他调用将等待桌子解锁。 – 2014-03-27 08:17:24

+0

嗨,这个SO问题有一些相关http://stackoverflow.com/questions/21086201/fill-in-missing-values我有一个表2列,datetime(与PK)和一个浮点数(它保存的值) 。系统正在监视一台机器,并且每〜10ms接收一个日期时间的数据,并且它应该被插入到表中。为了节省存储空间,计划只在与最后插入的值不同时插入值。所以表格结果应该看起来像我上面链接的SO问题。 – user3182508

+0

您应该无条件地将它们添加到不同的队列表中(即始终),然后使用过程将它们间隔移动到实际表中,然后可能不必每10ms运行一次。 –

回答

0

根据海报的评论的问题,C#代码从一个传感器接收的值。代码应该只在与以前的值不同时插入值。

,而不是在数据库解决这个,为什么没有代码存储的最后一个值插入如果新的值是不同的只是调用该程序?然后该过程将不需要检查数据库中是否存在该值;它可以简单地插入。这将会更有效率。

+0

这不会太慢吗?我从一个C#应用程序调用这个SP,然后我将不得不调用2个SP,一个用于选择,另一个用于插入。 – user3182508

+0

这对他的问题有什么好处?如果IF()和INSERT之间的时间已经太长以至于无法避免陈旧的数据,那么如何才能到数据库中查找来自IF()的信息,返回到机器,决定和(可能)执行INSERT可以更快吗?在数据库中解决这个问题正是这里需要的。 – deroby

+0

@deroby我已经更新了答案,以澄清我的意思。 – 2014-03-27 08:34:01

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 

假设你有一个唯一索引(PK?)在SensorTime上,这实际上应该相当快。

+0

传感器时间的确有一个PK。第二个似乎改善了很多,我会再测试一下 – user3182508