2011-10-31 118 views
0

只是希望得到一個問題我有一些看法/可能的線索。SQL DELETE語句刪除Didnt

我有一個存儲過程,從我的數據庫中的表更新/刪除記錄,它從中刪除的表是一個活動表,該臨時存儲數據,並且還更新存檔表上的記錄。 (用於報告等)。它正常工作,並沒有問題。

然而,近來我在一個窗口服務工作監督我們的系統(運行24/7),它使用一個HTTP調用來啓動一個程序,一旦這個程序完成它,然後運行提及存儲過程刪除了冗餘數據。基本上,該服務只是快速運行該程序,以確保其功能正常。

我最近注意到,數據總不是被刪除。通過查看日誌,我發現沒有錯誤被報告。甚至看到數據庫中的記錄已經正確更新。但只是不會被刪除。

不幸的是,監控服務會產生連鎖反應,因爲這會持續運行,併發出警報,因爲數據無法在活動表中複製,因此需要刪除數據。

目前我有一個適當的程序,以清除任何舊數據。 (3小時)。

結果的值是 - 拒絕。

下面是存儲過程:

DECLARE @PostponeUntil DATETIME; 
DECLARE @Attempts INT; 
DECLARE @InitialTarget VARCHAR(8); 
DECLARE @MaxAttempts INT; 
DECLARE @APIDate DATETIME; 

--UPDATE tCallbacks SET Result = @Result WHERE CallbackID = @CallbackID AND UPPER(Result) = 'PENDING'; 

UPDATE tCallbacks SET Result = @Result WHERE ID = (SELECT TOP 1 ID FROM tCallbacks WHERE CallbackID = @CallbackID ORDER BY ID DESC) 

SELECT @InitialTarget = C.InitialTarget, @Attempts = LCB.Attempts, @MaxAttempts = C.CallAttempts 
FROM tConfigurations C WITH (NOLOCK) 
LEFT JOIN tLiveCallbacks LCB ON LCB.ID = @CallbackID 
WHERE C.ID = LCB.ConfigurationID; 

IF ((UPPER(@Result) <> 'SUCCESSFUL') AND (UPPER(@Result) <> 'MAXATTEMPTS') AND (UPPER(@Result) <> 'DESTBAR') AND (UPPER(@Result) <> 'REJECTED')) BEGIN 
    --INSERT A NEW RECORD FOR RTNR/BUSY/UNSUCCESSFUL/REJECT 
    --Create Callback Archive Record 

    SELECT @APIDate = CallbackRequestDate FROM tCallbacks WHERE Attempts = 0 AND CallbackID = @CallbackID; 

    BEGIN TRANSACTION 
    INSERT INTO tCallbacks (CallbackID, ConfigurationID, InitialTarget, Agent, AgentPresentedCLI, Callee, CalleePresentedCLI, CallbackRequestDate, Attempts, Result, CBRType, ExternalID, ASR, SessionID) 
     SELECT ID, ConfigurationID, @InitialTarget, Agent, AgentPresentedCLI, Callee, CalleePresentedCLI, @APIDate, @Attempts + 1, 'PENDING', CBRType, ExternalID, ASR, SessionID 
     FROM tLiveCallbacks 
     WHERE ID = @CallbackID; 

    UPDATE LCB 
    SET PostponeUntil = DATEADD(second, C.CallRetryPeriod, GETDATE()), 
     Pending = 0, 
     Attempts = @Attempts + 1 
    FROM tLiveCallbacks LCB 
    LEFT JOIN tConfigurations C ON C.ID = LCB.ConfigurationID 
    WHERE LCB.ID = @CallbackID; 

    COMMIT TRANSACTION 
END 
ELSE BEGIN 
    -- Update the Callbacks archive, when Successful or Max Attempts or DestBar. 
    IF EXISTS (SELECT ID FROM tLiveCallbacks WHERE ID = @CallbackID) BEGIN 

     BEGIN TRANSACTION 
     UPDATE tCallbacks 
     SET Attempts = @Attempts 
     WHERE ID IN (SELECT TOP (1) ID 
          FROM tCallbacks 
          WHERE CallbackID = @CallbackID 
          ORDER BY Attempts DESC); 

     -- The live callback should no longer be active now. As its either been answered or reach the max attempts. 
     DELETE FROM tLiveCallbacks WHERE ID = @CallbackID; 
     COMMIT 
    END 
END 
+0

'@ Result'如何以及在哪裏設置?因爲看起來你在獲得'@ Result'和你做'IF'語句之間有競爭條件。您還應該考慮將整個存儲過程包裝在事務中,而不僅僅是「IF」語句的分支。 – Seph

+0

另一個關於問題可能來自哪裏的提示,是你如何檢查'tCallbacks'中的多個記錄是否存在給定的'CallbackID',這對你的數據是否可能? – Seph

+0

@Result作爲參數傳遞。對於我注意到這種情況,是在Result設置爲Rejected時。 CallbackID可以在tCallbacks中多次出現,因爲它必須爲每次嘗試都使用callbackID進行計數。我也想過把它包裝在try catch塊中,這會有幫助嗎? – Valeklosse

回答

2

你需要修復您的交易處理。發生的事情是一個語句失敗,但由於沒有try-catch語句塊,所有更改都只會回滾失敗的語句。

你不應該有一個的begin tran沒有try catch塊和錯誤回滾。我個人也喜歡這樣的東西把錯誤和關聯的數據放入一個表變量(它不會回滾),然後在回滾之後插入一個異常表。這樣數據保持完整性,您可以查看問題所在。

+0

非常感謝。我重新設計了存儲過程以便在事務中使用try catch塊,老實說,我最近才發現在SQL中存在try catch塊,當我最初在6個月前開發這個時,我不知道,所以回到過去碼。這對於使用異常表也是一個很好的主意。 – Valeklosse

+0

當幾個月來一直工作正常的事情停止工作時,異常表真的會有所幫助。 – HLGEM