SQL Server 2005의 한 명령문에서 두 개의 테이블을 업데이트하는 방법은 무엇입니까?


193

한 번에 두 개의 테이블을 업데이트하고 싶습니다. 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'

4
이유를 설명하면 도움이 될 것입니다.
Eric Mickelsen

2
SQL Server 2005는 하나의 쿼리에서 여러 테이블 업데이트를 지원하지 않습니다.
Pranav Singh

답변:


195

한 명령문에서 여러 테이블을 업데이트 할 수 없지만 트랜잭션을 사용하여 두 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;

실제로, 나는이 두 테이블의 레코드를 다른 임시 테이블에서 업데이트하고 있습니다. temptable에는 table1에 대한 링크가 있지만 table2에는 없습니다. 동일한 Table2 레코드를 업데이트하려면 어떻게해야합니까? 어떻게 연결합니까?
Jango

@unknown : 업데이트 쿼리에 세 번째 테이블의 키가 필요한 경우 Table2를 업데이트 할 때 사용자 의견에 따라 Table1과 Table2를 조인해야합니다. 그럼에도 불구하고 여전히 두 가지 별도의 업데이트를 수행해야합니다.
LBushkin

3
아마도 관련이 없습니다 : mysql의 업데이트 구문이 다르기 때문에 MYSQL에서는 작동하지 않습니다. Table1, Table2 SET을 업데이트해야합니다. Table1.LastName = 'DR. XXXXXX 'WHERE T1.id = T2.id
Juan Vilar

우리는 기본 키와 외래 키 관계를 유지해야합니까
srinivas gowda

2
또한 오류가 발생할 경우 부분 업데이트를 피하기 위해 update 문을 try / catch 블록 안에 넣어야합니다. 이 질문을 참조하십시오 : stackoverflow.com/questions/1749719/…
mechatroner

84

한 번에 두 개의 테이블을 업데이트 할 수 없지만을 사용하여 업데이트를 삽입에 연결할 수 있으며이 OUTPUT INTO출력을 두 번째 업데이트의 조인으로 사용할 수 있습니다.

DECLARE @ids TABLE (id int);
BEGIN TRANSACTION

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

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

COMMIT;

귀하의 예시 WHERE조건을 이외의 다른 필드로 변경했습니다 id. 그것이 id당신이이 공상을 필요로하지 않는 경우에 OUTPUT, 당신은 UPDATE동일한 두 번째 테이블을 할 수 있습니다 id='010008'.


이것이 가장 좋은 답변이며 원래 질문에 대한 진정한 답변으로 선정되어야합니다. 감사합니다. 그것은 나를 위해 일했다.
Fandango68

1
T1.field있어야하는데 Table1.field?
WAF

22

죄송합니다, 당신은 그렇게 할 수 없습니다. 두 개의 다른 테이블에서 속성을 업데이트하려면 두 개의 별도 명령문을 실행해야합니다. 그러나 배치에있을 수 있습니다 (한 번의 왕복으로 서버에 전송 된 SQL 세트)


2
어이! 나는 추가 kudos에 대해 더 자주 미안 단어를 사용해야합니다 : P
Fandango68

14

그것에 대한 짧은 대답은 아니오입니다. from업데이트 문의 절에 여러 테이블을 입력 할 수 있지만 update키워드 다음에 단일 테이블 만 지정할 수 있습니다 . "업데이트 가능한"보기 (단순히 특정 제한 사항을 따르는보기)를 작성하더라도 이와 같은 업데이트는 실패합니다. 다음은 MSDN 설명서의 관련 클립입니다 (강조 표시).

업데이트 (Transact-SQL)

table_or_view_name이 참조하는 뷰는 업데이트 가능해야하며 뷰 의 FROM 절에서 정확히 하나의 기본 테이블 을 참조해야합니다 . 업데이트 가능한 뷰에 대한 자세한 내용은 CREATE VIEW (Transact-SQL)를 참조하십시오.

뷰 만들기 (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 절의 영향을받지 않습니다.
  • 뷰의 select_statement에서 WITH CHECK OPTION 절과 함께 TOP은 사용되지 않습니다.

그러나 정직하게 말하면 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.


1
여러 테이블에 영향을주는 View 개체를 업데이트 할 수는 없지만 원본을 별도의 문으로 나누는 INSTEAD OF 트리거 를 만들 수 있습니다 (각 테이블에 영향을 미침).INSTEAD OF Specifies that the DML trigger is executed instead of the triggering SQL statement, therefore, overriding the actions of the triggering statements. INSTEAD OF cannot be specified for DDL or logon triggers.
4AM

9

이것은 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'

다중 명령문이 필요한 다중 테이블에 대한 업데이트를 수행하는 경우… 다른 조건에 따라 하나를 업데이트하는 경우 가능할 수 있습니다 ... 트랜잭션을 사용해야합니다. 


1
이 anser는 여전히 다른 사용자와 관련이 있습니다.
Kyselejsyreček

1
@ Kyselejsyreček이 답변은 모든 비용을 피해야합니다. MySQL에는 충분한 단점과 냄새가 있으며, 대부분은 실제로 지원되지 않지만 그 단점에 의존하는 코드가 깨지지 않도록 유지됩니다. 업그레이드는 쉽게 깨지거나 예기치 않은 동작 및 성능 문제가 발생할 수 있습니다
파나지오티스 Kanavos

7

트랜잭션 내에 두 개의 업데이트 문을 배치해야합니다.


2

한 테이블에 대해 update 문을 작성한 다음 첫 번째 테이블 업데이트 에 대한 트리거를 작성 하여 두 번째 테이블을 업데이트 할 수 있습니다.


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

-2

아래 표시된이 쿼리처럼 간단합니다.

UPDATE 
  Table1 T1 join Table2 T2 on T1.id = T2.id
SET 
  T1.LastName='DR. XXXXXX', 
  T2.WAprrs='start,stop'
WHERE 
  T1.id = '010008'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.