2016-06-21 62 views
1

同時我有表查詢像更新多個表在SQL

UPDATE D 
SET D.VALUE = B.VALUE 
FROM 
    DOM D 
INNER JOIN 
    COM C ON C.ID = D.ID 
INNER JOIN 
    TOM T ON T.ID = D. ID 
WHERE 
    D.VALUE <> B.VALUE 

UPDATE D 
SET C.VALUE = B.VALUE 
FROM 
    DOM D 
INNER JOIN 
    COM C ON C.ID = D.ID 
INNER JOIN 
    TOM T ON T.ID = D. ID 
WHERE 
    D.VALUE <> B.VALUE 

這裏where條件是這兩個查詢相同,也是連接是相同的。那麼我可以用一個update聲明更新這兩個表嗎?

+3

你不能用一條'update'語句更新多個表。 –

+1

您無法使用單個更新語句更新多個表,但可以將所有更新放入單個事務中,以便所有更新都將被提交或回滾。 –

回答

3

您無法使用一個Update語句更新TWO表。但您可以通過將兩個單獨的更新包裝到一個事務中來更新一個事務中的兩個表。它實現了同樣的事情,但方式稍有不同。

BEGIN TRANSACTION 

    UPDATE D 
    SET D.VALUE = B.VALUE 
    FROM 
    DOM D 
    INNER JOIN COM C ON C.ID = D.ID 
    INNER JOIN TOM T ON T.ID = D. ID 
    WHERE D.VALUE <> B.VALUE 

    UPDATE D 
     SET C.VALUE = B.VALUE 
    FROM 
    DOM D 
    INNER JOIN COM C ON C.ID = D.ID 
    INNER JOIN TOM T ON T.ID = D. ID 
    WHERE D.VALUE <> B.VALUE 

COMMIT TRANSACTION 
+0

我會添加'開始嘗試...結束嘗試開始趕上...結束趕上' –

+0

@AlexKudryashev是的,如果問題是布特錯誤處理我會建議,但問題是關於更新:) –

+2

「它實現了相同東西「 - 幾乎。在每個語句結束時檢查約束。因此,如果您有一對更新,其中任一個本身會導致違反約束條件,但是如果一起考慮約束條件,那麼執行兩個單獨的更新與假設的「更新」不是「同一件事」多個表同時「聲明。當然,如果我們在SQL Server中有可延遲的約束條件,我們可以更接近於說事務中的多個更新與單個更新相同。 –

0

最明顯的解決方案是在DOM表上編寫更新觸發器。這個觸發器將處理TOM和COM表。

Select 1 ID, 10 Value 
into DOM 
union all 
Select 2, 20 
union all 
Select 3, 30 


Select 1 ID, 10 Value 
into TOM 
union all 
Select 2, 20 
union all 
Select 3, 30 


Select 1 ID, 10 Value 
into COM 
union all 
Select 2, 20 
union all 
Select 3, 30 


drop trigger DomUpdate 
create trigger DomUpdate on DOM 
after Update 
as 
begin 
Update TOM 
set value = i.value 
from TOM t 
INNER JOIN 
    inserted I ON I.ID = T. ID 

Update COM 
set value = i.value 
from TOM t 
INNER JOIN 
    inserted I ON I.ID = T. ID 
end 
GO 

Select D.value 
FROM 
    DOM D 
INNER JOIN 
    COM C ON C.ID = D.ID 
INNER JOIN 
    TOM T ON T.ID = D. ID 
WHERE 
    D.VALUE <> 50 

begin tran t1 
Update D 
set D.value = 50 
FROM 
    DOM D 
INNER JOIN 
    COM C ON C.ID = D.ID 
INNER JOIN 
    TOM T ON T.ID = D. ID 
WHERE 
    D.VALUE <> 50 
--rollback tran t1 
commit tran t1 

Select * from DOM 
Select * from COM 
Select * from TOM