본문 바로가기
Back-End/SQL

[MySql] 하나의 쿼리문을 여러번 반복하려면?

by SeanK 2022. 1. 2.

 

3 tier 아키텍처의 마지막 관문, 드디어 Database 기초학습을 완료했다. 

 

이제 Mysql를 프로그래밍적으로 제어하기 위해서 서버에서 쿼리문을 보내는 방법을 실습해보다가 한 가지 문제에 부딪혔다. 

 

'하나의 쿼리문을 인자만 바꿔서 반복해야 하면 어떻게 해야 하지?'  

 

 

예를 들어, order_items과 같은 주문-주문제품 조인 테이블에 한 주문에 포함되어 있는 여러 제품에 대한 정보(어떤 주문에 어떤 제품들이 포함되어 있고 각 제품 당 가격 정보)를 insert 해야 하는 상황이면 어떻게 해야 할까?

 

for문을 떠올릴 수 있지만 for문은 올바른 해결법이 아니다. 

for문을 사용하면 insert 쿼리문을 여러번 서버 측에 보내게 되는데 만약 error가 발생하면?

이는 쿼리문의 ACID 법칙을 위배할 가능성이 다분히 높다. 

 

다행히 mysql 라이브러리에서는 굉장히 유연하게 인자를 전달하는 방법을 미리 구축해 놓았다. 

 

Performing queries

 

1. 기본적인 .query() 작성법

 

.query(sqlString, callback)

 

mysql의 가장 기본적인 쿼리문 작성방법은 위와 같다. 아마 대부분의 초보 개발자들은 위의 형식만을 알고 있는 상태일 것이다. 

sqlString인자에는 쿼리문을 넣고 callback문에는 쿼리를 진행한 후 에러 처리나 결과 처리를 하는 콜백 함수가 위치한다. 

 

connection.query('SELECT * FROM `books` WHERE `author` = "David"', function (error, results, fields) {
  // error will be an Error if one occurred during the query
  // results will contain the results of the query
  // fields will contain information about the returned results fields (if any)
});

 

2. 변수값을 넣는. query() 작성법

 

.query(sqlString, values, callback)

 

자 여기서 mysql 라이브러리의 유연함을 느낄 수 있는 부분이다. 첫 번째 인자와 세 번째 인자는 1번 작성법과 동일하지만 두 번째 인자로 values가 추가된 것을 볼 수 있다. 

 

values인자는 sqlString에 "?"로 설정된 부분에 어떤 값을 대입하면 되는지 알려주는 인자다. 

아래의 예시를 보면 author 옆에 ?로 표시가 된 것을 확인할 수 있다. 

그리고 values 부분에 David가 들어가 있기 때문에 쿼리문은 author에 David를 넣어 보내지게 된다. 

 

만약 "?" 가 여러 개라면 values에 있는 순서대로 대입이 되기 때문에, 

변수가 여러개라도 순서에 맞춰서 유연하게 쿼리문을 작성할 수 있다.

 

connection.query('SELECT * FROM `books` WHERE `author` = ?', ['David'], function (error, results, fields) {
  // error will be an Error if one occurred during the query
  // results will contain the results of the query
  // fields will contain information about the returned results fields (if any)
});

 

만약에 위처럼 변수가 하나뿐이라면 배열 대신에 스트링을 넣어도 된다. 

 

connection.query(
  'SELECT * FROM `books` WHERE `author` = ?',
  'David',
  function (error, results, fields) {
    // error will be an Error if one occurred during the query
    // results will contain the results of the query
    // fields will contain information about the returned results fields (if any)
  }
);

 

3. 객체를 통한 .query() 작성법

 

.query(options, callback)

이 방식은 options 인자에 쿼리 문과 변수 및 여러 옵션을 객체로 만들어 넣는 방식이다. 

 

바로 예제를 살펴보자. 

 

connection.query({
  sql: 'SELECT * FROM `books` WHERE `author` = ?',
  timeout: 40000, // 40s
  values: ['David']
}, function (error, results, fields) {
  // error will be an Error if one occurred during the query
  // results will contain the results of the query
  // fields will contain information about the returned results fields (if any)
});

 

위의 예제를 보면 sql 프로퍼티에 쿼리문을 설정한 뒤 values 프로퍼티에 값을 설정한 것을 확인할 수 있다. 이외에 timeout 등 여러 옵션들도 같이 넣어 작성을 할 수 있다. 이전 1번 2번 보다 좀 더 심도 있게 여러 가지 설정을 추가하면서 쿼리문을 작성하고 싶을 때 유용하게 사용할 수 있는 방법이라고 생각된다. 

 

 

자 이제 mysql 라이브러리에서 쿼리문을 작성하는 세 가지 방법에 대해 알아보았다. 

 

그렇다면 서두에서 밝힌 문제를 해결하기 위해선 어떤 방법을 사용하면 되는 것일까?

 

두번째, 세 번째 쿼리문을 이용하면 간단하게 해결이 되는데, 이 중 필자는 두 번째 쿼리문을 이용해 아래와 같이 작성해 볼 수 있을 것으로 생각된다. 

 

const subQuery = `INSERT INTO order_items (order_id, item_id, order_quantity) VALUES ?`;


db.query(subQuery, [params], (error, result) => {
callback(error, result);
});

 

 

'Back-End > SQL' 카테고리의 다른 글

[MySql] 연속된 여러 쿼리문 질의하기  (0) 2022.01.02
[SQL] SQL join 정리  (0) 2021.12.20