주문하기
Table delivery {
id integer [primary key]
address varchar
receiver varchar
contact varchar
}
Table orders {
id integer [primary key]
delivery_id integer
book_title varchar
total_quantity integer
total_price integer
created_at timestamp
user_id integer
}
Table orderedBook {
id integer [primary key]
order_id integer
book_id integer
quantity integer
}
세 개의 테이블을 사용한다.
테이블 상 delivery 부터 insert 하고 orders insert, 마지막으로 orderedBook insert 해야한다.
주문하기를 위한 SQL 문이다.
// 주문하기
//배송 정보 입력
INSERT INTO deliveries (address, receiver, contact)
VALUES ('서울시 중구', '김철수', '010-1234-5678')
//주문 정보 입력
INSERT INTO delivery (address, receiver, contact)
VALUES ('서울시 중구', '김철수', '010-1234-5678')
//주문 상세 목록 입력
INSERT INTO orderedBooks (order_id, book_id, quantity)
VALUES (1, 1, 1);
방금 insert 한 데이터 pk 가져오는 방법
LAST_INSERT_ID()
: 이전 값을 들고오는 오류가 날 수도 있음MAX()
: 이것을 사용하는게 좋다.
MAX()
max 를 어떻게 사용하면 좋을까? 이는 한가지 예시이다.
INSERT INTO orders (book_title, total_quantity, total_price, user_id, delivery_id)
VALUES ("어린왕자들", 3, 60000, 1, (SELECT max(id) FROM deliveries));
이와 같이 부분 쿼리문으로 사용할 수도 있고
INSERT INTO deliveries (address, receiver, contact)
VALUES ('서울시 중구', '김철수', '010-1234-5678')
const delivery_id = SELECT max(id) FROM deliveries
INSERT INTO orders (book_title, total_quantity, total_price, user_id, delivery_id)
VALUES ("어린왕자들", 3, 60000, 1, delivery_id);
이와 같이 변수로 뺀후 다시 넣어줄 수도 있다.
하지만 좀 더 편리한 방법도 존재한다
postman 에 result 값을 표시해주고 있다. result 값을 잘 보면 insertId 라는 값이 보이는데 이 값이 우리가 원하는 그 값이다. 따라서 max를 사용해 쿼리를 다시 쳐줄 필요 없이 바로 꺼내서 쓸수 있다.
벌크 INSERT
orderedBook 테이블에 Insert 를 하기 위해서는 items 배열에 있는 책들을 하나하나 꺼내서 SQL문으로 INSERT를 해주어야한다. 이를 위해 items.forEach 문을 사용할 수 있다.
sql = `INSERT INTO orderedBooks (order_id, book_id, quantity)
VALUES ?;`;
values = [];
items.forEach((item) => {
values.push([order_id, item.book_id, item.quantity])
}
)
conn.query(sql, [values], (err, results) => {
if(err) {
console.log(err);
return res.status(StatusCodes.INTERNAL_SERVER_ERROR);
}
return res.status(StatusCodes.OK).json(results);
})
하나씩 SQL 문을 쳐서 하는 대신 좋은 방법이 있다. 2차원 배열을 이용하는 것이고 그 배열이 들어갈 자리는 ?로 표시해두는 것이다.
검증 과정
코드의 주석을 풀고 모든 sql문을 한번에 실행시켜보면 새로운 오류가 생긴다.
conn.query(sql, values, (err, results) => {
if(err) {
console.log(err);
return res.status(StatusCodes.INTERNAL_SERVER_ERROR);
}
delivery_id = results.insertId;
console.log("results.insertId", results.insertId);
console.log("conn.query - delivery_id", delivery_id);
})
console.log("out - delivery_id", delivery_id);
위 코드의 결고 콘솔 로그로는 "results.insertId", "conn.query - delivery_id", "out - delivery_id" 순서로 찍혀야할 것 같지만 실제로는 그렇지 않다.
"out - delivery_id" , "results.insertId", "conn.query - delivery_id" 순서로 찍히게 되고 심지어 conn.query 바깥에서 찍은 로그에서는 delivery_id 가 undefined 로 나온다. 이게 어떻게 된 일 일까?
후기
주문하기 api 를 구현하였고 마지막에 문제점을 아직 남겨두었다.
키워드: 프로그래머스 데브코스, 국비지원교육, 코딩부트캠프
'프로그래머스 풀스택 데브코스 > 데브코스 TIL' 카테고리의 다른 글
웹 풀사이클 데브코스 TIL 39일차 (0) | 2024.01.11 |
---|---|
웹 풀사이클 데브코스 TIL 38일차 (0) | 2024.01.10 |
웹 풀사이클 데브코스 TIL 36일차 (0) | 2024.01.09 |
웹 풀사이클 데브코스 TIL 35일차 (0) | 2024.01.07 |
웹 풀사이클 데브코스 TIL 34일차 (0) | 2024.01.04 |