[기획자의 개발일기]

SQL 스크립트에서 왜 '?'를 사용할까?

완벽한 장면 2024. 12. 30. 14:50

SQL 스크립트에서 왜 ?를 사용할까?

역시 비교봇 / 등록봇 코드를 보다가, ?이 하도 많아서, 기억을 더듬어볼 겸 ?의 사용에 대해 정리를 해보았다.

 

1. 물음표 기호(?)의 쓰임

- SQL의 '자리 표시자(Placeholder)'로 사용된다.

: SQL 쿼리에서 동적으로 값을 삽입할 때 데이터베이스에 직접 값을 넣는 대신에 ?로 자리를 표시한다.

 => 이후, JavaScript에서 values 배열에 실제 데이터를 채우면 데이터베이스가 이를 바인딩하여 처리한다.

 

 

2. 물음표 기호 사용 목적

1) 보안 강화

- SQL 인젝션 방지

: SQL 쿼리에 값을 직접 삽입하면 보안 문제가 발생할 수 있다(ex: SQL 인젝션 공격).

=> ?를 사용하면 값이 안전하게 바인딩되므로 SQL 인젝션을 방지할 수 있다.

 

아래와 같은 경우가, input 에 이상한 값 넣어버리면 답이 안 나온다.

let query = `SELECT * FROM users WHERE username = '${input}' AND password = '${password}'`;

 

 

 

 

- ? 사용으로 공격 방지

: ?를 사용하면 값이 자동으로 이스케이프(Escaping) 처리되어 안전하게 쿼리에 포함된다.

사용 예시)

let query = `SELECT * FROM users WHERE username = ? AND password = ?`;

 

2) 코드 가독성 및 유지보수성 향상

- 값이 많을 경우, 값을 동적으로 추가하는 방식이 가독성을 높이고 유지보수를 쉽게 만든다.

- 코드에서 ?와 values 배열을 사용하면 데이터와 쿼리를 분리하여 더 간결하고 안전한 코드를 작성할 수 있다.

 

 

 

3. 예제 코드에서의 쓰임

- 이 값을 사용하는 예시 코드 일부를 가져와 보았다.

const placeholders = productInfo.map(product => {
    values.push(shopName, product.productName, product.productNo, product.productPrice, product.productType, product.maxOrderCount, product.minOrderCount,
        product.orderUnit, product.stock, product.isOutOfStock, changeType, product.specification, product.imagePath, JSON.stringify(product.discountInfo),
        nowTime, nowTime, useYn, JSON.stringify(product.changedFields));
    return '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
}).join(',');

 

 

한 상품 데이터에 대한 자리 표시자 생성

- (?, ?, ?, ..., ?)는 SQL에서 **하나의 행(row)**에 대한 자리 표시자이다.

ex) INSERT INTO tb_products (...) VALUES (?, ?, ?, ..., ?)와 같이 하나의 상품 정보를 삽입하는 자리 표시자이다.

 

여러 상품 데이터의 자리 표시자 생성

- productInfo.map()은 productInfo 배열을 순회하면서 각 상품에 대해 (?, ?, ?, ..., ?)를 생성한다.

- 최종적으로 다수의 상품을 처리하기 위해 쉼표(,)로 연결한다.

 

예제

const productInfo = [
    { productName: 'Product A', productNo: '123', productPrice: 100, ... },
    { productName: 'Product B', productNo: '124', productPrice: 200, ... }
];

 

 

 

위의 데이터를 처리하면 다음과 같이 자리 표시자가 생성이 된다.

(?, ?, ?, ..., ?), (?, ?, ?, ..., ?)

- 첫 번째 (?, ?, ?, ..., ?)는 첫 번째 상품에 대한 자리 표시자.
- 두 번째 (?, ?, ?, ..., ?)는 두 번째 상품에 대한 자리 표시자.

 

 

이와 동시에, values 배열에는 실제 값이 추가된다.

[
    'ShopName', 'Product A', '123', 100, ..., // 첫 번째 상품 데이터
    'ShopName', 'Product B', '124', 200, ...  // 두 번째 상품 데이터
]

 

 

4. 최종 SQL 결과

- '?' 는 values 배열의 값으로 대체된다.

INSERT INTO tb_products (shopName, productName, ..., changedFields) 
VALUES (?, ?, ?, ..., ?), (?, ?, ?, ..., ?);

 

 

728x90
반응형