2016-06-21 118 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