나만의 작은 도서관
[TIL][C++] 250828 MMO 서버 개발 89일차: C++의 ODBC API와 SQLBindParameter() 본문
Today I Learn
[TIL][C++] 250828 MMO 서버 개발 89일차: C++의 ODBC API와 SQLBindParameter()
pledge24 2025. 8. 29. 21:48주의사항: 해당 글은 일기와 같은 기록용으로, 다듬지 않은 날것 그대로인 글입니다.
C++의 ODBC API와 SQLBindParameter()
C++에서 제공하는 ODBC API
- C++에서는 “sql.h”, “sqlext.h”m “sqltypes.h”와 같은 헤더 파일이 존재하며 이 헤더 파일들을 include 하면 ODBC API를 사용할 수 있다.
- 제공하는 ODBC(Open DB Connectivity)는 개방형 데이터베이스 접속 표준으로, 어떤 DB 제품군(ex. Oralcle, SQL Server, MySql)을 사용하든 상관없이 일관된 인터페이스로 접근할 수 있다.
- 게다가 특정 IDE(ex. Visual Studio, CLion)에도 구애받지 않기 때문에 어떤 IDE를 사용하든 컴파일러가 C++ 표준을 지원하고 ODBC 드라이버 및 헤더 파일에 접근할 수 있는 컴파일러라면 ODBC API를 활용할 수 있다.
SQLBindParameter() 함수
- SQLBindParameter함수는 ODBC에서 SQL 문에 매개변수를 바인딩할 때 사용하는 함수. 여기서 매개변수란 ‘?’를 의미한다.
- Ex. INSERT INTO Employee VALUES(?, ?, ?)
SQLBindParameter 함수 구조
SQLRETURN SQLBindParameter(
SQLHSTMT StatementHandle,
SQLUSMALLINT ParameterNumber,
SQLSMALLINT InputOutputType,
SQLSMALLINT ValueType,
SQLSMALLINT ParameterType,
SQLULEN ColumnSize,
SQLSMALLINT DecimalDigits,
SQLPOINTER ParameterValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
);
매개변수 리스트 타입 설명
- SQLRETURN: 함수의 실행 결과를 나타내는 타입
- Ex. SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR 등이 있음
- SQLHSTMT: SQL문을 처리하기 위한 핸들(Handle). SQL 처리 담당 직원이라 생각하면 된다.
- SQLUSMALLINT: unsigned 정수 타입.
- SQLULEN: unsigned 긴 정수 타입. 주로 문자열 또는 바이너리 데이터의 최대 길이를 지정할 때 사용한다.
- SQLPOINTER: 제너릭 포인터 타입. 바인딩할 매개변수의 값이 저장된 메모리 주소가 들어간다. (C++의 변수 포인터가 들어간다는 뜻)
- SQLLEN: 긴 정수 타입. SQL문에서 활용하는 데이터의 논리적인 길이를 의미한다.
- 버퍼의 실제 길이, 데이터 길이 또는 NULL 여부 지정에 사용.
매개변수 상세 설명
SQLRETURN SQLBindParameter(
SQLHSTMT StatementHandle, -> SQL문 핸들
SQLUSMALLINT ParameterNumber, -> 바인딩할 매개변수 번호(1부터 시작)
SQLSMALLINT InputOutputType, -> 매개변수 입출력 타입 설정
SQLSMALLINT ValueType, -> 매개변수의 C언어 데이터 타입
SQLSMALLINT ParameterType, -> 매개변수의 SQL 데이터 타입
SQLULEN ColumnSize, -> SQL 기준 타입 최대 길이. ex. VARCHAR(50)이면 50을 지정
SQLSMALLINT DecimalDigits, -> 소수점 이하 자릿수 지정
SQLPOINTER ParameterValuePtr,-> 바인딩할 변수의 주소
SQLLEN BufferLength, -> ParameterValuePtr이 가리키는 버퍼의 길이(크기?)
SQLLEN * StrLen_or_IndPtr); -> 바인딩 변수의 실제 길이 또는 Null 여부 포인터
}
InputOutputType 종류
- SQL_PARAM_INPUT: 데이터를 DB로 전달. 가장 많이 사용되며 프로시저 호출이 아닌 경우 100% 이거다.
- SQL_PARAM_OUTPUT: DB에서 결과를 받는 타입.
- ?=call GetNextEmpID
- SQL_PARAM_INPUT_OUTPUT: 데이터를 DB로 전달하고, 그 결과를 다시 받는다.
고정 길이 타입과 가변 길이 타입 처리하는 법
- 타입을 다룰 때 int, float, bool과 같은 고정 길이 타입이 있고, 문자열, 바이너리 데이터와 같은 가변 길이 타입이 있다. SQLBindParameter는 데이터 타입에 따라 바인딩할 때 사용하는 인자가 다르다.
고정 길이 타입
- 고정 길이 타입의 데이터의 경우, 사용자가 추가적으로 데이터 길이를 알려주지 않아도 데이터 길이를 알 수 있다. 따라서, 가변 길이에서만 사용하는 인자들은 넣어주긴 하되 내부적으로 무시된다. 무시되는 인자는 다음과 같다.
- BufferLength
- StrLen_or_IndPtr
- 추가적으로 ColumnSize의 경우 일부 타입은 무시된다.
가변 길이 타입
- 가변 길이 타입의 데이터의 경우, 사용자가 추가적으로 데이터 길이를 알려줘야 한다. 즉, 바이너리 타입과 문자열 타입은 고정 길이 타입에서 무시한 BufferLength와 StrLen_or_IndPtr을 설정해줘야 한다.
- BufferLength는 데이터를 담을 버퍼의 최대 크기를 지정한다.
- StrLen_or_IndPtr: 버퍼에 들어있는 실제 데이터의 크기를 넣어준다. 아니면 SQL_NTS와 같은 특별한 값으로 데이터의 끝을 알리는 문자를 지정한다.
[-------데이터-------________]
BufferLength = 버퍼의 최대 길이
StrLen_or_IndPtr = 데이터의 길이(바이트 단위)
char name[100] = "John"; // 버퍼는 100바이트
SQLLEN actualLength = 4; // 실제 데이터는 4바이트
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR,
50, 0, name, 100, &actualLength);
어떻게 가변 길이로 판단되는가?
- valueType과 parameterType으로 판단한다. valueType이 SQL_C_CHAR, SQL_C_WCHAR, SQL_C_BINARY와 같은 타입이고, parameterType이 SQL_VARCHAR, SQL_NVARCHAR, SQL_VARBINARY와 같은 타입이면 가변 길이로 판단한다.
