MySQL, 하나의 쿼리로 여러 테이블 업데이트


132

세 개의 테이블을 업데이트하는 함수가 있지만이를 수행하기 위해 세 개의 쿼리를 사용합니다. 좋은 연습을 위해보다 편리한 접근 방식을 사용하고 싶습니다.

단일 쿼리로 MySQL에서 여러 테이블을 업데이트하려면 어떻게해야합니까?


3
생성 된 코드의 예를 제공 할 수 있습니까? 테이블 사이에 공통 키가 있습니까?
Jonathan Day

답변:


451

두 테이블의 경우를 타고, Books하고 Orders. 표 Order.ID = 1002에서 와 같이 특정 순서로 장부의 수를 늘리는 경우 Orders재고에서 사용할 수있는 총 도서 수를 Books표 에서 같은 수만큼 줄 이도록해야 합니다.

UPDATE Books, Orders
SET Orders.Quantity = Orders.Quantity + 2,
    Books.InStock = Books.InStock - 2
WHERE
    Books.BookID = Orders.BookID
    AND Orders.OrderID = 1002;

SQL 쿼리에 "LIMIT"를 포함하려면 LIMIT 1 또는 LIMIT 2를 말해야합니까?
Bluedayz

2
이 거래와 거래의 이점은 무엇입니까? 감사!
paulkon 2009 년

2
@ paulkon, 나는 트랜잭션을 사용할 때 트랜잭션의 절차가 실패하면 롤백을 사용할 수 있어야하기 때문에 많은 오버 헤드가 있다고 가정합니다.
Thijs Riezebeek

27
이 쿼리를 사용할 때의 일반적인 경고. WHERE 절은 각 테이블에 대해 별도로 평가됩니다. Books.BookID = Orders.BookID가 없으면 매우 중요합니다. Books 테이블 업데이트는 지정된 ID를 가진 행뿐만 아니라 모든 행에 발생합니다. 어떤 교훈은 어려운 방식으로 배우고,이 교훈은 무서운 방식으로 배웠습니다.
nheimann1

1
@ nheimann1 그리고 이것이 바로 사람들이 항상 ANSI "inner join"구문을 사용하도록 권장하는 이유입니다. 그 상태를 잊어 버리는 대신 너무 많은 직교 조인을 얻는 것은 너무 쉽습니다.
fool4jesus

77
UPDATE t1
INNER JOIN t2 ON t2.t1_id = t1.id
INNER JOIN t3 ON t2.t3_id = t3.id
SET t1.a = 'something',
    t2.b = 42,
    t3.c = t2.c
WHERE t1.a = 'blah';

이것이 무엇을 업데이트할지 보려면, 이것을 select 문으로 변환하면됩니다 :

SELECT t2.t1_id, t2.t3_id, t1.a, t2.b, t2.c AS t2_c, t3.c AS t3_c
FROM t1
INNER JOIN t2 ON t2.t1_id = t1.id
INNER JOIN t3 ON t2.t3_id = t3.id
WHERE t1.a = 'blah';

다른 답변과 동일한 테이블을 사용하는 예 :

SELECT Books.BookID, Orders.OrderID,
    Orders.Quantity AS CurrentQuantity,
    Orders.Quantity + 2 AS NewQuantity,
    Books.InStock AS CurrentStock,
    Books.InStock - 2 AS NewStock
FROM Books
INNER JOIN Orders ON Books.BookID = Orders.BookID
WHERE Orders.OrderID = 1002;

UPDATE Books
INNER JOIN Orders ON Books.BookID = Orders.BookID
SET Orders.Quantity = Orders.Quantity + 2,
    Books.InStock = Books.InStock - 2
WHERE Orders.OrderID = 1002;

편집하다:

재미를 위해 조금 더 흥미로운 것을 추가해 봅시다.

의 테이블 books과의 테이블 이 있다고 가정 해 봅시다 authors. 당신 books은 있습니다 author_id. 그러나 데이터베이스가 처음 만들어 졌을 때 외래 키 제약 조건이 설정되지 않았고 나중에 프론트 엔드 코드의 버그로 인해 일부 도서가 유효하지 않은 author_ids 로 추가되었습니다 . DBA는 필요한 사항 books을 확인하기 위해이 모든 과정을 거치지 않아도 author_id되므로 데이터 캡처 담당자 books가 올바른 지점을 가리 키도록 결정합니다 authors. 그러나 각 책을 통과하기에는 너무 많은 책 author_id이 있으며 실제와 일치하는 책 author이 정확 하다는 것을 알고 있다고 가정 해 봅시다 . 존재하지 않는 것입니다author_id유효하지 않은 사용자가 도서 세부 정보를 업데이트 할 수있는 인터페이스가 이미 있으며 개발자는이 문제에 대해서만 변경하고 싶지 않습니다. 그러나 기존 인터페이스는을 수행 INNER JOIN authors하므로 저자가 잘못된 모든 책은 제외됩니다.

"알 수없는 저자"와 같은 가짜 저자 레코드를 삽입하십시오. 그런 다음 author_id알 수없는 작성자를 가리 키도록 모든 잘못된 레코드를 업데이트하십시오 . 그런 다음 데이터 캡처자는 저자가 "알 수없는 저자"로 설정된 모든 책을 검색하고 올바른 저자를 찾아서 고칠 수 있습니다.

알 수없는 작성자를 가리 키도록 모든 불량 레코드를 어떻게 업데이트합니까? 이처럼 (알 수없는 저자 author_id는 99999 라고 가정 ) :

UPDATE books
LEFT OUTER JOIN authors ON books.author_id = authors.id
SET books.author_id = 99999
WHERE authors.id IS NULL;

위는 또한 업데이트됩니다 books이 그 NULL author_id알 수없는 저자. 원하지 않으면 물론을 추가 할 수 있습니다 AND books.author_id IS NOT NULL.


35

다음과 같이 조인을 사용하여 하나의 쿼리 로이 작업을 수행 할 수도 있습니다.

UPDATE table1,table2 SET table1.col=a,table2.col2=b
WHERE items.id=month.id;

물론이 쿼리 하나만 보내면됩니다. 조인에 대한 자세한 내용은 http://dev.mysql.com/doc/refman/5.0/en/join.html을 참조하십시오 . 이 주문에 대한 몇 가지 제한 사항이기도 여러 테이블에 제한하면 여기에 대해 읽을 수 있습니다 업데이트 : http://dev.mysql.com/doc/refman/5.0/en/update.html ( "가입"F 단지 CTRL +).


"join"이라고 부르는 것이 관대합니다. ;-)
underscore_d

2

일반적으로 저장 프로 시저의 목적은 다음과 같습니다. 여러 SQL 문을 순서대로 구현합니다. 롤백을 사용하면 데이터 일관성을 유지하기 위해 하나의 작업 단위 (즉, 모두 실행되거나 아예 수행되지 않음)로 처리되도록 할 수 있습니다.


절차는 어디에서 작성합니까? 예를 들어 주시겠습니까?
Adamski

1
원자 성의 필요성을 설명하기 위해 찬성 투표-저장 프로 시저를 사용하는 것만 일관성을 보장하지는 않지만 여전히 트랜잭션을 사용해야 함을 인식해야합니다. 마찬가지로 트랜잭션이 동일한 연결을 통해 수행되는 경우 저장 프로 시저를 사용하지 않고도 트랜잭션을 수행 할 수 있습니다. 이 경우 다중 테이블 업데이트를 사용하는 것이 훨씬 좋습니다.
던컨

2

여러 쿼리를 말할 때 다음과 같이 여러 SQL 문을 의미합니다.

UPDATE table1 SET a=b WHERE c;
UPDATE table2 SET a=b WHERE d;
UPDATE table3 SET a=b WHERE e;

또는 다음과 같이 여러 쿼리 함수 호출

mySqlQuery(UPDATE table1 SET a=b WHERE c;)
mySqlQuery(UPDATE table2 SET a=b WHERE d;)
mySqlQuery(UPDATE table3 SET a=b WHERE e;)

전자는 단일 mySqlQuery 호출을 사용하여 수행 할 수 있습니다. 원하는 경우 다음 방식으로 mySqlQuery 함수를 호출하면됩니다.

mySqlQuery(UPDATE table1 SET a=b WHERE c; UPDATE table2 SET a=b WHERE d; UPDATE table3 SET a=b WHERE e;)

이것은 하나의 mySqlQuery () 호출로 세 개의 쿼리를 모두 실행합니다.


mySqlQuery ()는 사용자 정의 함수입니까 아니면 내장 함수입니까? 이것에 대해 더 알고 싶습니다.
Debashis

3
쿼리 함수가 매번 새 연결을 여는 경우를 제외하고 세 개의 쿼리를 개별적으로 또는 여러 개의 쿼리로 보내는 것에는 큰 차이가 없습니다. 서버 측 실행의 관점에서 똑같습니다
Duncan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.