如何在SQL Server 2005中的一个语句中更新两个表?

Jan*_*ngo 183 sql t-sql sql-server sql-server-2005

我想一次更新两个表.我如何在SQL Server 2005中这样做?

UPDATE 
  Table1, 
  Table2
SET 
  Table1.LastName='DR. XXXXXX', 
  Table2.WAprrs='start,stop'
FROM 
  Table1 T1, 
  Table2 T2
WHERE 
  T1.id = T2.id
AND 
  T1.id = '010008'
Run Code Online (Sandbox Code Playgroud)

LBu*_*kin 186

您无法在一个语句中更新多个表,但是,您可以使用事务来确保UPDATE以原子方式处理两个语句.您也可以批量处理它们以避免往返.

BEGIN TRANSACTION;

UPDATE Table1
  SET Table1.LastName = 'DR. XXXXXX' 
FROM Table1 T1, Table2 T2
WHERE T1.id = T2.id
and T1.id = '011008';

UPDATE Table2
SET Table2.WAprrs = 'start,stop'
FROM Table1 T1, Table2 T2
WHERE T1.id = T2.id
and T1.id = '011008';

COMMIT;
Run Code Online (Sandbox Code Playgroud)

  • 可能没有关系:这对MYSQL不起作用,因为mysql的更新语法不同.你必须去UPDATE Table1,Table2 SET Table1.LastName ='DR.XXXXXX'WHERE T1.id = T2.id (3认同)
  • 您还应该将更新语句放在 try/catch 块中,以避免出现错误时进行部分更新。看到这个问题:http://stackoverflow.com/questions/1749719/sql-server-transactions-roll-back-on-error (2认同)

Rem*_*anu 78

您不能一次更新两个表,但可以使用OUTPUT INTO将更新链接到插入,并且可以将此输出用作第二个更新的连接:

DECLARE @ids TABLE (id int);
BEGIN TRANSACTION

UPDATE Table1 
SET Table1.LastName = 'DR. XXXXXX'  
OUTPUT INSERTED.id INTO @ids
WHERE T1.field = '010008';

UPDATE Table2 
SET Table2.WAprrs = 'start,stop' 
FROM Table2 
JOIN @ids i on i.id = Table2.id;

COMMIT;
Run Code Online (Sandbox Code Playgroud)

我将你的示例WHERE条件改为某个字段而不是id,如果是id你不需要这个花哨的OUTPUT,你可以只为相同的id ='010008'更新第二个表.

  • 这是最佳答案,应该被选为原始问题的真实答案。谢谢。这对我有用。 (2认同)

Cha*_*ana 20

对不起,afaik,你做不到.要更新两个不同表中的属性,您需要执行两个单独的语句.但它们可以在一个批处理中(一组往返一次发送到服务器的SQL)

  • 天哪!对于更多的荣誉,我应该更经常使用“对不起”一词:P (2认同)

jve*_*zey 14

对此的简短回答是否定的.虽然可以在fromupdate语句的子句中输入多个表,但只能在update关键字后指定一个表.即使您确实编写了"可更新"视图(这只是一个遵循某些限制的视图),这样的更新也会失败.以下是MSDN文档中的相关剪辑(重点是我的).

更新(Transact-SQL)

table_or_view_name引用的视图必须是可更新的,并且只引用视图的FROM子句中的一个基表.有关可更新视图的更多信息,请参见CREATE VIEW(Transact-SQL).

CREATE VIEW(Transact-SQL)

只要满足以下条件,您就可以通过视图修改基础基表的数据:

  • 任何修改(包括UPDATE,INSERT和DELETE语句)都必须引用一个基表中的列.
  • 要在视图中修改的列必须直接引用表列中的基础数据.无法以任何其他方式派生列,例如通过以下方式:
    • 聚合函数:AVG,COUNT,SUM,MIN,MAX,GROUPING,STDEV,STDEVP,VAR和VARP.
    • 一个计算.无法从使用其他列的表达式计算列.通过使用集合运算符UNION,UNION ALL,CROSSJOIN,EXCEPT和INTERSECT形成的列相当于计算并且也不可更新.
  • 要修改的列不受GROUP BY,HAVING或DISTINCT子句的影响.
  • TOP不会在视图的select_statement中的任何位置与WITH CHECK OPTION子句一起使用.

但是,老实说,根据LBushkin的例子,你应该考虑在事务中使用两个不同的SQL语句.

更新:我可以在可更新视图中更新多个表的原始断言是错误的.在SQL Server 2005和2012上,它将生成以下错误.我已经纠正了我的回答以反映这一点.

Msg 4405, Level 16, State 1, Line 1

View or function 'updatable_view' is not updatable because the modification affects multiple base tables.


Mic*_*ick 7

您应该在事务中放置两个更新语句


小智 7

这适用于MySQL,实际上只是一个隐式事务,但它应该是这样的:

UPDATE Table1 t1, Table2 t2 SET 
t2.field = t2.field+2,
t1.field = t1.field+2

WHERE t1.id = t2.foreign_id and t2.id = '123414'
Run Code Online (Sandbox Code Playgroud)

如果您正在对需要多语句的多表进行更新...如果您更新一个,则可能更新,而另一个基于其他条件...您应该使用事务. 

  • 答案不正确,因为OP要求"SQL Server"更新. (12认同)
  • @Kyselejsyreček 应该不惜一切代价避免这个答案。MySQL 有足够多的怪癖和味道,其中大部分实际上不受支持,但保留下来以避免破坏依赖于这些怪癖的代码。升级很容易破坏它们或导致意外的行为和性能问题 (3认同)