2011-12-20 229 views
2

我想在事務中實現類似下面的sql語句。任何人都可以建議我怎麼做到這一點?最重要的是,不應該有任何髒讀或寫。謝謝!SQL Server查詢問題

UPDATE items SET assigned = 1 
WHERE 
    SELECT TOP 1 @item_no = item_no 
    FROM items 
    WHERE item_code = @item_code 
    AND store_id = @store_id 

UPDATE parts SET issued = 1 
WHERE 
    SELECT TOP 1 @part_no = part_no 
    FROM parts 
    WHERE part_id = part_id 

INSERT INTO issued_hardware (@item_no, @part_no, DateTime.now, @username); 
+0

我假設你的意思是不應該有任何髒讀或寫?如果是這樣,修復它。 – kba 2011-12-20 07:00:37

+0

謝謝指出這一點。 – pothios 2011-12-20 09:49:33

回答

0

正如其他人所提到的,您使用事務及其隔離狀態來控制髒讀取。我建議不要這樣做,因爲這意味着您可以閱讀可能失敗的未提交的事務,這可能會導致難以追查的競爭狀況。

此外,由於您正在做更多的一個數據修改,您應該明確回滾您的交易。最後你的SQL需要修復。利用輸出條款可能是一個好主意。

BEGIN TRANSACTION; 

BEGIN TRY 


    DECLARE @Item table (item_no int) 
    DECLARE @part table (part_no int) 

    UPDATE TOP 1 ITEMS 
    SET assigned = 1 
    WHERE 
      item_code = @item_code 
      AND store_id = @store_id 
    OUTPUT 
      inserted.item_no 
    INTO @Item 

    UPDATE TOP 1 parts 
    SET issued = 1 
    OUTPUT 
      inserted.part_no 
    INTO @part 


    INSERT INTO issued_hardware 
    SELECT item_no, GetDate(), @UserName 
    FROM @item, @part; 





END TRY 
BEGIN CATCH 
    IF @@TRANCOUNT > 0 
     ROLLBACK TRANSACTION; 
END CATCH; 

IF @@TRANCOUNT > 0 
    COMMIT TRANSACTION; 
GO 
+0

嗨,只是想知道其他事務是否可以覆蓋item參數和part參數值這會導致插入不準確。 – pothios 2011-12-20 07:22:27

+0

變量本地批處理或存儲過程是執行本地的,所以不能被覆蓋。 – 2011-12-20 07:25:01

+0

我使用command.CommandText =「這裏的sql語句」 你是否建議我應該將其更改爲存儲過程並從我的方法調用它? – pothios 2011-12-20 07:27:01

1

問題不明確,但我會盡力回答。

你只是試圖框

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 
BEGIN TRAN 

your query here 

COMMIT 

之間的查詢,不要忘記用圓括號,或別的東西來框住子查詢 - 因爲你的查詢都是不syntaxically正確

,尤其是 - 如果你想從你的transaciton中的其他交易數據髒讀 - 使用表(nolock)後綴

2

你只需要啓用適當的隔離級別並封裝你的查詢BEGIN TRAN identifierCOMMIT TRAN identifier

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; 
BEGIN TRAN T1; 
UPDATE items SET assigned = 1 
WHERE 
    SELECT TOP 1 @item_no = item_no 
    FROM items 
    WHERE item_code = @item_code 
    AND store_id = @store_id; 

UPDATE parts SET issued = 1 
WHERE 
    SELECT TOP 1 @part_no = part_no 
    FROM parts 
    WHERE part_id = part_id; 

INSERT INTO issued_hardware (@item_no, @part_no, DateTime.now, @username); 
COMMIT TRAN T1; 
0

請提供更多詳細信息。你使用什麼編程語言?什麼組件連接到數據庫?你在MS Visual Studio中編寫應用程序嗎?

還是你只是試圖在一個腳本中執行所有這一切,在一個單一的事務?乍一看,我建議將上面的所有代碼放入存儲的MSSQL過程中,然後從應用程序的代碼中調用過程。這樣,您可以提交或還原整個事務,並將邏輯保存在數據庫的一個地方。此外,修改SQL中的過程並保持比需要重新編譯的應用程序更容易。

+0

即時通訊使用visual studio和ms sql 2008.即時通訊方法執行查詢 – pothios 2011-12-20 07:14:28

+0

好的,請參閱[此鏈接](http://www.codeproject.com/KB/database/transactions.aspx)描述使用ADO事務。關鍵是要使用db.BeginTransaction(),transaction.Commit()和transaction.Rollback() – talereader 2011-12-20 08:34:56

+0

至於在ADO中使用存儲過程,請參見[this](http://www.codeproject.com/KB/cs/ simplecodeasp.aspx)。另外,如果是這種情況,問題與.Net中的db事務有關,那麼你應該考慮編輯你的問題並添加標籤C#和.Net – talereader 2011-12-20 08:41:14