[MYSQL] BULK INSERT, 벌크 인서트 : 여러 데이터를 한번에 INSERT 하기

Seungeun·2024년 6월 1일

백엔드 기초

목록 보기
2/3
post-thumbnail

문제상황

주문했을 때 주문id - (장바구니 아이템 id, 개수)로 연결해주는 테이블을 만들고 있었다. 한번 주문할 때 여러개의 장바구니 아이템이 담기기 때문에
여러 데이터를 SELECT해서 INSERT해야 하는 상황

INSERT VALUES에 여러 SELECT 넣기

먼저 내가 작성한 코드는 이러하다.

let order_id = 1;
let items = [
  {
    cart_id : 1,
    item_id : 1,
    quantity : 2
	}, 
  {
    cart_id: 2,
    item_id: 4,
    quantity :1
	}
]

 items.forEach(async (item) => {
    let sql = `INSERT INTO orderedbooks (order_id, book_id, quantity) 
                VALUES (?, 
						(SELECT item_id FROM cartItems WHERE id = ?),
                		(SELECT quantity FROM cartItems WHERE id = ?))`;
  	val = [order_id,item.cart_id,item.cart_id];
  	await conn.execute(sql, val);

여기서 주의할 것은

VALUES (order_id, (SELECT item_id, quantity FROM cartItems WHERE id = ?)

이런 식으로 SELECT를 한번에 여러개하면 error가 났다.

첫번째 코드로 작성하면 잘 INSERT가 되었다.
for문으로 INSERT를 item개수만큼 실행한 것.
여기서 고민한 것이 많은 수의 데이터를 SELECT해서 INSERT할 때는 첫번째 방법이 복잡할 것 같은데 좀 더 쉬운 방법이 없을까였다.(for문을 너무 많이 돌리는 것이 아닐까..)

결국 알아낸 것이

벌크인서트(BULK INSERT)

let order_id = 1;
let items = [
  {
    cart_id : 1,
    item_id : 1,
    quantity : 2
	}, 
  {
    cart_id: 2,
    item_id: 4,
    quantity :1
	}
]

let sql = `INSERT INTO orderedItem (order_id, item_id, quantity) VALUES ?`;

let val = [];
items.forEach((item) => {
  val3.push([order_id, item.item_id, item.quantity])
        })
let [result3] = await conn.query(sql, [val]);
} 

sql문은 한번만 돌리면 되는 방법! 벌크 인서트

  1. 배열을 [values]형태로 conn.query(sql, [values])에 넣어주면 된다.
  2. execute는 적용이 안된다.

결과 sql = INSERT INTO orderedbooks (order_id, book_id, quantity) VALUES (1,1,2),(1,4,1)

profile
Wonderland

0개의 댓글