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

时间:2010-01-11 19:49:21

标签: sql sql-server sql-server-2005 tsql

我想一次更新两个表。我如何在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'

11 个答案:

答案 0 :(得分:177)

您无法在一个语句中更新多个表,但是,您可以使用事务来确保以原子方式处理两个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;

答案 1 :(得分:76)

您不能一次更新两个表,但可以使用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;

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

答案 2 :(得分:18)

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

答案 3 :(得分:14)

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

UPDATE (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.

答案 4 :(得分:7)

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

答案 5 :(得分:6)

这适用于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'

如果您正在对需要多语句的多表进行更新...如果您更新一个表,则可能更新,然后根据其他条件进行更新...您应该使用事务。

答案 6 :(得分:1)

您可以为一个表编写更新语句,然后在第一个表更新中编写触发器,更新第二个表

答案 7 :(得分:0)

从我的角度来看,您可以执行此操作,它是SQL SERVER中两个表的一对一更新:

 BEGIN TRANSACTION

      DECLARE @CNSREQ VARCHAR(30)
      DECLARE @ID INT
      DECLARE @CNSRQDT VARCHAR(30)
      DECLARE @ID2 INT

      DECLARE @IDCNSREQ INT
      DECLARE @FINALCNSREQ VARCHAR(30)
      DECLARE @FINALCNSRQDT VARCHAR(30)
      DECLARE @IDCNSRQDT INT


      SET @CNSREQ=(SELECT MIN(REQUISICIONESDT.CNSREQ) FROM REQUISICIONESDT
          INNER JOIN 
              REQUISICIONES
                ON REQUISICIONESDT.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
           AND REQUISICIONES.CNSREQ = REQUISICIONESDT.CNSREQ AND REQUISICIONESDT.IDREQ = REQUISICIONES.ID
        WHERE REQUISICIONES.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID)

      SELECT REQUISICIONES.CNSREQ, REQUISICIONES.ID, REQUISICIONES.CNSRQDT FROM REQUISICIONES
       INNER JOIN 
          REQUISICIONESDT
              ON REQUISICIONESDT.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
               AND REQUISICIONES.CNSREQ = REQUISICIONESDT.CNSREQ AND REQUISICIONESDT.IDREQ = REQUISICIONES.ID
        WHERE REQUISICIONES.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
    AND REQUISICIONES.CNSREQ = @CNSREQ

        UPDATE REQUISICIONESDT SET  REQUISICIONESDT.CNSREQ=NULL, REQUISICIONESDT.IDREQ=NULL
          FROM REQUISICIONES INNER JOIN REQUISICIONESDT
             ON REQUISICIONESDT.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
       WHERE REQUISICIONES.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
      AND REQUISICIONES.CNSREQ = @CNSREQ

        UPDATE REQUISICIONES SET REQUISICIONES.CNSRQDT=NULL, REQUISICIONES.IDRQDT=NULL
          FROM REQUISICIONES INNER JOIN REQUISICIONESDT
          ON REQUISICIONESDT.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
       WHERE REQUISICIONES.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
     AND REQUISICIONES.CNSREQ = @CNSREQ

       SET @ID2=(SELECT MIN(REQUISICIONESDT.ID) FROM REQUISICIONESDT
        WHERE ISNULL(REQUISICIONESDT.IDREQ,0)<>0)
     DELETE FROM REQUISICIONESDT WHERE REQUISICIONESDT.ID=@ID2


      SET @IDCNSREQ=(SELECT MIN (REQUISICIONES.ID)FROM REQUISICIONES
          INNER JOIN REQUISICIONESDT ON
        REQUISICIONESDT.CEDULA = REQUISICIONES.CEDULA AND REQUISICIONES.FECHA_SOLICITUD = REQUISICIONESDT.FECHA_SOLICITUD
         WHERE REQUISICIONES.CNSRQDT IS NULL AND REQUISICIONES.IDRQDT IS NULL)

        SET @FINALCNSREQ=(SELECT MIN (REQUISICIONES.CNSREQ)FROM REQUISICIONES
            INNER JOIN REQUISICIONESDT ON
        REQUISICIONESDT.CEDULA = REQUISICIONES.CEDULA AND REQUISICIONES.FECHA_SOLICITUD = REQUISICIONESDT.FECHA_SOLICITUD
         WHERE REQUISICIONES.CNSRQDT IS NULL AND REQUISICIONES.IDRQDT IS NULL)

         SET @FINALCNSRQDT=(SELECT MIN(REQUISICIONESDT.CNSRQDT) FROM REQUISICIONES
           INNER JOIN REQUISICIONESDT ON
          REQUISICIONESDT.CEDULA = REQUISICIONES.CEDULA AND REQUISICIONES.FECHA_SOLICITUD = REQUISICIONESDT.FECHA_SOLICITUD
           WHERE REQUISICIONES.CNSRQDT IS NULL AND REQUISICIONES.IDRQDT IS NULL)

          SET @IDCNSRQDT=(SELECT MIN (REQUISICIONESDT.ID)FROM REQUISICIONES
           INNER JOIN REQUISICIONESDT ON
         REQUISICIONESDT.CEDULA = REQUISICIONES.CEDULA AND REQUISICIONES.FECHA_SOLICITUD = REQUISICIONESDT.FECHA_SOLICITUD  
         WHERE REQUISICIONES.CNSRQDT IS NULL AND REQUISICIONES.IDRQDT IS NULL)

           UPDATE REQUISICIONES SET REQUISICIONES.CNSRQDT = @FINALCNSRQDT, REQUISICIONES.IDRQDT=@IDCNSRQDT FROM REQUISICIONES
            INNER JOIN REQUISICIONESDT ON
             REQUISICIONESDT.CEDULA = REQUISICIONES.CEDULA AND REQUISICIONES.FECHA_SOLICITUD = REQUISICIONESDT.FECHA_SOLICITUD
            WHERE REQUISICIONESDT.CNSRQDT = @FINALCNSRQDT AND REQUISICIONESDT.ID = @IDCNSRQDT 


ROLLBACK TRANSACTION

答案 8 :(得分:0)

对于基于 Table2 特定列的常规更新 table1 特定列,此查询完美运行:

UPDATE table 1  
SET Col 2 = t2.Col2,  
    Col 3 = t2.Col3  
FROM table1 t1  
INNER JOIN table 2 t2 ON t1.Col1 = t2.col1 

答案 9 :(得分:-1)

就像下面显示的查询一样简单。

UPDATE 
  Table1 T1 join Table2 T2 on T1.id = T2.id
SET 
  T1.LastName='DR. XXXXXX', 
  T2.WAprrs='start,stop'
WHERE 
  T1.id = '010008'

答案 10 :(得分:-1)

您可以在一个查询中更新两个表。

UPDATE Table1, Table2 
SET Table1.LastName="DR. XXXXXX", Table2.WAprrs="start,stop" 
WHERE Table1.id=Table2.id AND Table1.id="010008";