2014-03-27 50 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