INSERT 후 PK 값 얻기

Gaeun·2023년 1월 16일
1

wecode TIL

목록 보기
21/24

장바구니에서 결제로 넘어간 후, order 테이블에 해당 유저의 정보를 INSERT한 뒤, order 테이블에 INSERT된 id 값을 알아낸 뒤, order_product 테이블에 해당 유저와 order.id와 상품의 정보를 입력하려고 하였다.

1. LAST_INSERT_ID()

이를 위해 처음에는 아래와 같이 LAST_INSERT_ID()를 사용하였다. LAST_INSERT_ID()는 최근 INSERT한 데이터의 id, 혹은 AUTO_INCREMENT에 따라 생성된 최근 id를 반환하는데, 이를 사용하는 것이 내가 원하는 구현 사항을 충족하는 것이라고 생각하였다.

await appDataSource.query(
	`INSERT INTO
        orders (user_id, order_status_id)	
	VALUES
        (?, 1);
    `, [userId]
);

const lastInsertOrderId = await appDataSource.query(
	`SELECT LAST_INSERT_ID();`
);

return lastInsertOrderId[0]["LAST_INSERT_ID()"];

위의 스크린샷을 보면, 숫자를 뽑아내기 위해 변수명과 몇 번째 인덱스, 그리고 그 키의 이름을 적어 INSERT된 id를 찾을 수 있었다.

하지만... 역시나... 멘토 호준님께서 아래와 같이 코멘트를 달아주셨다.

이 힌트를 통하여 구글링을 하였으나, 처음에는 MyBatis를 사용하는 방법, 혹은 LAST_INSERT_ID()를 사용하는 방법 외에는 별다른 소득이 없었고, 이렇게 해내지 못하는 걸까라는 생각을 하였다. 그러다가 호준님이 '실행하면 결과로 insertId를 받을 수 있으니'라고 쓰신 것에 집중하여 구글링의 방향을 바꾸어보았다.

2. The Result Object

W3schools의 Node.js MySQL Insert Into 페이지에서 내가 원하는 답을 찾을 수 있었다.

The Result Object

  • When executing a query, a result object is returned.
  • The result object contains information about how the query affected the table.
  • The result object returned from the example above looks like this:
{
  fieldCount: 0,
  affectedRows: 14,
  insertId: 0,
  serverStatus: 2,
  warningCount: 0,
  message: '\'Records:14  Duplicated: 0  Warnings: 0',
  protocol41: true,
  changedRows: 0
}

쿼리를 실행하게 될 때, 결과 객체가 반환되며, 결과 객체에는 쿼리가 테이블에 미치는 영향에 대한 정보가 포함되어 있다는 것을 알게 되었다.

그래서 나는 아래와 같이 나의 코드를 다시 작성해보았다.

const createOrder = await queryRunner.query(
	`INSERT INTO
        orders (user_id, order_status_id)
	VALUES
        (${userId}, ${OrderStatusId.ORDER_DONE});
	`
);

const orderId = createOrder.insertId;

두 번의 쿼리(INSERT & SELECT)를 실행하여 INSERT된 PK id값을 받아왔던 첫 번째의 방법(LAST_INSERT_ID())과는 달리, 한 번의 쿼리로 INSERT한 후, 그 result objcet를 통해 insertId를 받아오는 두 번째 방법이 훨씬 경제적이고 가독성이 훨씬 높아졌다!

profile
🌱 새싹 개발자의 고군분투 코딩 일기

1개의 댓글

comment-user-thumbnail
2023년 1월 24일

LAST_INSERT_ID() 를 쓰기 위해 굳이 쿼리문을 하나 더 넣었어야 했는데 이런 방법이 있었군요...! 😃 가은님도 호준님도 리스펙... 🌟 2차 플젝때 저도 이거 써볼래요! 🤩

답글 달기