[트러블 슈팅][Node.js] ER_WRONG_ARGUMENTS 오류 중 mysqld_stmt_execute

Young Min Kang·2024년 6월 1일

트러블 슈팅

목록 보기
3/5
post-thumbnail

ER_WRONG_ARGUMENTS 오류 중 mysqld_stmt_execute

장바구니 조회(선택한 상품 목록 조회)에서 사용자 id를 jwt 토큰으로 변경 및 비동기 처리를 하다 발생한 오류이다.

문제😲

에러 코드

const getCartItem = async (req, res) => {
    const conn = await connection();
    const {selected} = req.body; // selected = [cartItemsId1, cartItemsId2...]

    try {
        const {user_id} = ensureAuthorization(req);
        console.log(user_id);
        console.log(selected);
        let sql = `SELECT cartItems.id, book_id, title, summary, quantity, price, price*quantity as total_price
                    FROM cartItems
                    JOIN books ON(cartItems.book_id = books.id)
                    WHERE user_id = ? AND cartItems.id IN (?)`;
        let values = [user_id, selected];   

        const results = await conn.execute(sql, values);
        return res.status(StatusCodes.OK).json(results[0]);
    } catch (err) {
        console.error(err);
        return res.status(StatusCodes.BAD_REQUEST).end();
    }
};
const ensureAuthorization = (req) => {
    let receivedJwt = req.headers["authorization"];
    let decodedJwt = jwt.verify(receivedJwt, process.env.PRIVATE_KEY);

    return decodedJwt
}

받으려고 하는 형식

에러 상황 및 메시지

BAD_REQUEST 400 을 띄우는 상황이였다.

   code: 'ER_WRONG_ARGUMENTS',
   errno: 1210,
   sql: 'SELECT cartItems.id, book_id, title, summary, quantity, price, price*quantity as total_price\n' +
     '                    FROM cartItems\n' +
     '                    JOIN books ON(cartItems.book_id = books.id)\n' +
     '                    WHERE user_id = ? AND cartItems.id IN (?)',
   sqlState: 'HY000',
   sqlMessage: 'Incorrect arguments to mysqld_stmt_execute'

해결🚀

어디가 문제인지 몰라서 2개를 확인해 보았다.

  1. user_id, seleted를 제대로 받았는지 확인
  2. DB에 저장된 형태가 올바른지 확인

답답하게도 위의 사항들은 이상이 없었다.

그러다가 에러 메시지에 좀 더 치중하여 분석해보니, execute 라는 단어가 강조되어 보였다.

혹시나 하여 execute를 사용하지 않고 query로 변경을 하니 에러가 해결됐다.

  • execute: 프리페어드 스테이트먼트의 제한으로 인해 배열 파라미터를 제대로 처리하지 못해 오류가 발생한다.
    Prepared Statement로 쿼리를 컴파일하고, 실행 시 매개변수를 바인딩하여 처리하는 방식이다.
    즉, execute는 배열 파라미터를 단일 값으로 취급할 수 있어 IN (?) 구문을 처리하는 데 문제가 발생하게 된다.
  • query: 배열 파라미터를 직접 처리하므로 IN (?) 구문이 제대로 작동하여 오류가 발생하지 않는다.
    Direct Execution으로 query는 직접 쿼리를 실행하며, 배열 파라미터를 인라인으로 처리한다.

최종✔️

최종 코드

const getCartItem = async (req, res) => {
    const conn = await connection();
    const {selected} = req.body; // selected = [cartItemsId1, cartItemsId2...]

    try {
        const {user_id} = ensureAuthorization(req);
        console.log(user_id);
        console.log(selected);
        let sql = `SELECT cartItems.id, book_id, title, summary, quantity, price, price*quantity as total_price
                    FROM cartItems
                    JOIN books ON(cartItems.book_id = books.id)
                    WHERE user_id = ? AND cartItems.id IN (?)`;
        let values = [user_id, selected];   

        const results = await conn.query(sql, values);
        return res.status(StatusCodes.OK).json(results);
    } catch (err) {
        console.error(err);
        return res.status(StatusCodes.BAD_REQUEST).end();
    }
};
const ensureAuthorization = (req) => {
    let receivedJwt = req.headers["authorization"];
    let decodedJwt = jwt.verify(receivedJwt, process.env.PRIVATE_KEY);

    return decodedJwt
}

결과 사진

profile
꾸준히 한걸음씩

0개의 댓글