// 아래와 같이 직접적으로 타입을 지정하다보니
// SQL_INTEGER, SQL_C_LONG
// 실수의 요소가 많다
ASSERT_CRASH(dbConn->BindParam(1, SQL_C_LONG, SQL_INTEGER, sizeof(gold), &gold, &len));
int32 outId = 0;
SQLLEN outIdLen = 0;
ASSERT_CRASH(dbConn->BindCol(1, SQL_C_LONG, sizeof(outId), &outId, &outIdLen));
int32 outGold = 0;
SQLLEN outGoldLen = 0;
ASSERT_CRASH(dbConn->BindCol(2, SQL_C_LONG, sizeof(outGold), &outGold, &outGoldLen));
// ...
개선해보자
class DBConnection
{
// ...
public:
bool BindParam(int32 paramIndex, bool* value, SQLLEN* index);
bool BindParam(int32 paramIndex, float* value, SQLLEN* index);
bool BindParam(int32 paramIndex, double* value, SQLLEN* index);
bool BindParam(int32 paramIndex, int8* value, SQLLEN* index);
bool BindParam(int32 paramIndex, int16* value, SQLLEN* index);
bool BindParam(int32 paramIndex, int32* value, SQLLEN* index);
bool BindParam(int32 paramIndex, int64* value, SQLLEN* index);
bool BindParam(int32 paramIndex, TIMESTAMP_STRUCT* value, SQLLEN* index);
bool BindParam(int32 paramIndex, const WCHAR* str, SQLLEN* index);
bool BindParam(int32 paramIndex, const BYTE* bin, int32 size, SQLLEN* index);
bool BindCol(int32 columnIndex, bool* value, SQLLEN* index);
bool BindCol(int32 columnIndex, float* value, SQLLEN* index);
bool BindCol(int32 columnIndex, double* value, SQLLEN* index);
bool BindCol(int32 columnIndex, int8* value, SQLLEN* index);
bool BindCol(int32 columnIndex, int16* value, SQLLEN* index);
bool BindCol(int32 columnIndex, int32* value, SQLLEN* index);
bool BindCol(int32 columnIndex, int64* value, SQLLEN* index);
bool BindCol(int32 columnIndex, TIMESTAMP_STRUCT* value, SQLLEN* index);
bool BindCol(int32 columnIndex, WCHAR* str, int32 size, SQLLEN* index);
bool BindCol(int32 columnIndex, BYTE* bin, int32 size, SQLLEN* index);
private:
bool BindParam(SQLUSMALLINT paramIndex, SQLSMALLINT cType, SQLSMALLINT sqlType, SQLULEN len, SQLPOINTER ptr, SQLLEN* index);
bool BindCol(SQLUSMALLINT columnIndex, SQLSMALLINT cType, SQLULEN len, SQLPOINTER value, SQLLEN* index);
void HandleError(SQLRETURN ret);
// ...
DB Bind를 지원해줄 클래스도 만들어 보자
- DBBind
실제 사용은 이렇게
// Add Data
for (int32 i = 0; i < 3; i++)
{
DBConnection* dbConn = GDBConnectionPool->Pop();
DBBind<3, 0> dbBind(*dbConn, L"INSERT INTO [dbo].[Gold]([gold], [name], [createDate]) VALUES(?, ?, ?)");
int32 gold = 100;
dbBind.BindParam(0, gold);
WCHAR name[100] = L"루키스";
dbBind.BindParam(1, name);
TIMESTAMP_STRUCT ts = {2021, 6, 5};
dbBind.BindParam(2, ts);
ASSERT_CRASH(dbBind.Execute());
// Read
{
DBConnection* dbConn = GDBConnectionPool->Pop();
DBBind<1, 4> dbBind(*dbConn, L"SELECT id, gold, name, createDate FROM [dbo].[Gold] WHERE gold = (?)");
int32 gold = 100;
dbBind.BindParam(0, gold);
int32 outId = 0;
int32 outGold = 0;
WCHAR outName[100];
TIMESTAMP_STRUCT outDate = {};
dbBind.BindCol(0, OUT outId);
dbBind.BindCol(1, OUT outGold);
dbBind.BindCol(2, OUT outName);
dbBind.BindCol(3, OUT outDate);
ASSERT_CRASH(dbBind.Execute());
wcout.imbue(locale("kor"));
while (dbConn->Fetch())
{
wcout << "Id: " << outId << " Gold : " << outGold << " Name: " << outName << endl;
wcout << "Date : " << outDate.year << "/" << outDate.month << "/" << outDate.day << endl;
}
GDBConnectionPool->Push(dbConn);