SQLite - 쿼리 실행
저장소/VC++닥치고 샘플 ㄱㄱ~
// Insert에 사용될 데이터 구조체
typedef struct _my_value
{
// 이것 저것 있음
} MY_VALUE, *PMY_VALUE;
sqlite3* g_pDB = NULL;
int TestFunc_Open(const char* pszDBFilePath);
int TestFunc_Close();
int TestFunc_QueryExec1(const char* pszTableName,
const char* pszQuery,
sqlite3_callback xCallback);
sqlite3_callback xCallback);
int TestFunc_QueryExec2(const char* pszTableName, const char* pszQuery);
int TestFunc_QE_Insert(const char* pszTableName,
int nColumnCount,
std::list<PMY_VALUE>* plstValues);
std::list<PMY_VALUE>* plstValues);
int TestFunc_Open(const char* pszDBFilePath)
{
// 파라미터검증 생략
int nRet = SQLITE_OK;
nRet = sqlite3_open_v2(pszDBFilePath,
int nRet = SQLITE_OK;
nRet = sqlite3_open_v2(pszDBFilePath,
&g_pDB,
SQLITE_OPEN_READWRITE,
NULL);
SQLITE_OPEN_READWRITE,
NULL);
if(SQLITE_OK != nRet)
{
{
// 이쯤에서 적절한 에러처리.
}
return 0;
return 0;
}
int TestFunc_Close()
{
int TestFunc_Close()
{
if(NULL != g_pDB)
{
{
int nRet = SQLITE_OK;
nRet = sqlite3_close(g_pDB);
if(SQLITE_OK != nRet)
{
nRet = sqlite3_close(g_pDB);
if(SQLITE_OK != nRet)
{
// 아이고~ 실패입니다요! 에러처리!
}
}
return 0;
return 0;
}
/*
sqlite3_exec 함수를 사용한 방식
sqlite3_exec 함수는 내부에서 아래와 같은 과정으로 처리됨.
(sqlite3_prepare -> sqlite3_step -> sqlite3_finalize)
단일 명령 처리에는 사용하기 편하지만
빠르고 연속적인 쿼리를 처리하기엔 오버헤드를 무시할 수 없음.
*/
int TestFunc_QueryExec1(const char* pszTableName,
/*
sqlite3_exec 함수를 사용한 방식
sqlite3_exec 함수는 내부에서 아래와 같은 과정으로 처리됨.
(sqlite3_prepare -> sqlite3_step -> sqlite3_finalize)
단일 명령 처리에는 사용하기 편하지만
빠르고 연속적인 쿼리를 처리하기엔 오버헤드를 무시할 수 없음.
*/
int TestFunc_QueryExec1(const char* pszTableName,
const char* pszQuery,
sqlite3_callback xCallback)
sqlite3_callback xCallback)
{
// 파라미터 및 이것저것 검증 생략
int nRet = SQLITE_OK;
char* pszErrMsg = NULL;
nRet = sqlite3_exec(g_pDB, pszQuery, xCallback, NULL, &pszErrMsg);
if(SQLITE_OK != nRet)
{
int nRet = SQLITE_OK;
char* pszErrMsg = NULL;
nRet = sqlite3_exec(g_pDB, pszQuery, xCallback, NULL, &pszErrMsg);
if(SQLITE_OK != nRet)
{
// 실패 원인 확인 1. Code
int nErrCode = sqlite3_errcode(g_pDB);
// 실패 원인 확인 2. Message
const char* pszErrMessage = sqlite3_errmsg(g_pDB);
// 실패 원인 확인 3. 반환된 Error Message
// pszErrMsg <- 요거요거
// 반환된 Error Message는 알아볼거 알아보고 나중에
// sqlite3_free를 통해 메모리 해제를 해줘야 한다고 한다.
// (참고로 잘못된 대상으로 sqlite3_free를 사용하면 뻗어버린다!)
sqlite3_free((void*)pszErrMsg);
int nErrCode = sqlite3_errcode(g_pDB);
// 실패 원인 확인 2. Message
const char* pszErrMessage = sqlite3_errmsg(g_pDB);
// 실패 원인 확인 3. 반환된 Error Message
// pszErrMsg <- 요거요거
// 반환된 Error Message는 알아볼거 알아보고 나중에
// sqlite3_free를 통해 메모리 해제를 해줘야 한다고 한다.
// (참고로 잘못된 대상으로 sqlite3_free를 사용하면 뻗어버린다!)
sqlite3_free((void*)pszErrMsg);
}
return 0;
return 0;
}
/*
sqlite3_prepare 함수를 사용한 방식
sqlite3_exec 함수를 사용한 것보다 귀찮긴 하지만
sqlite3_bind_xxx 함수와 sqlite3_reset 함수를 활용하여 쿼리의 재사용성을 높일 수 있다.
작업의 끝은 sqlite3_finalize 함수 호출로 막을 내린다.
*/
int TestFunc_QueryExec2(const char* pszTableName, const char* pszQuery)
{
/*
sqlite3_prepare 함수를 사용한 방식
sqlite3_exec 함수를 사용한 것보다 귀찮긴 하지만
sqlite3_bind_xxx 함수와 sqlite3_reset 함수를 활용하여 쿼리의 재사용성을 높일 수 있다.
작업의 끝은 sqlite3_finalize 함수 호출로 막을 내린다.
*/
int TestFunc_QueryExec2(const char* pszTableName, const char* pszQuery)
{
// 파라미터 및 이것저것 검증 생략
int nRet = SQLITE_OK;
sqlite3_stmt* pStmt = NULL;
// 실행할 쿼리를 준비하고
nRet = sqlite3_prepare(g_pDB, pszQuery, -1, &pStmt, NULL);
if(SQLITE_OK == nRet)
{
int nRet = SQLITE_OK;
sqlite3_stmt* pStmt = NULL;
// 실행할 쿼리를 준비하고
nRet = sqlite3_prepare(g_pDB, pszQuery, -1, &pStmt, NULL);
if(SQLITE_OK == nRet)
{
// 준비된 쿼리를 실행한다.
nRet = sqlite3_step(pStmt);
while(SQLITE_ROW == nRet)
{
while(SQLITE_ROW == nRet)
{
// 뭐 필요한 작업 있으면 여기서
nRet = sqlite3_step(pStmt);
}
nRet = sqlite3_finalize(pStmt);
nRet = sqlite3_finalize(pStmt);
}
else
{
else
{
// 에러처리
}
return 0;
}
int TestFunc_QE_Insert(const char* pszTableName,
int TestFunc_QE_Insert(const char* pszTableName,
int nColumnCount,
std::list<PMY_VALUE>* plstValues)
std::list<PMY_VALUE>* plstValues)
{
// 파라미터 및 이것저것 검증 생략
// 대량의 INSERT를 처리할 경우 BEGIN ~ COMMIT 을 쓰면 속도가 빠르다고 함.
// 임시파일 어쩌구 하던데 자세히 모르니까 나중에 다시 찾아보도록...
int nRet = SQLITE_OK;
nRet = sqlite3_exec(g_pDB, "BEGIN;", NULL, NULL, NULL);
char szBind[100] = "?";
for(int i = 0 ; i < nColumnCount ; i++)
{
// 대량의 INSERT를 처리할 경우 BEGIN ~ COMMIT 을 쓰면 속도가 빠르다고 함.
// 임시파일 어쩌구 하던데 자세히 모르니까 나중에 다시 찾아보도록...
int nRet = SQLITE_OK;
nRet = sqlite3_exec(g_pDB, "BEGIN;", NULL, NULL, NULL);
char szBind[100] = "?";
for(int i = 0 ; i < nColumnCount ; i++)
{
strncat_s(szBind, 100, ", ?", _TRUNCATE);
}
char szQuery[512] = {0,};
strncpy_s(szQuery, 512, "INSERT INTO ", _TRUNCATE);
strncat_s(szQuery, 512, pszTableName, _TRUNCATE);
strncat_s(szQuery, 512, " VALUES(", _TRUNCATE);
strncat_s(szQuery, 512, szBind, _TRUNCATE);
strncat_s(sqQuery, 512, ");", _TRUNCATE);
sqlite3_stmt* pStmt = NULL;
nRet = sqlite3_prepare(g_pDB, szQuery, -1, &pStmt, NULL);
if(SQLITE_OK == nRet)
{
char szQuery[512] = {0,};
strncpy_s(szQuery, 512, "INSERT INTO ", _TRUNCATE);
strncat_s(szQuery, 512, pszTableName, _TRUNCATE);
strncat_s(szQuery, 512, " VALUES(", _TRUNCATE);
strncat_s(szQuery, 512, szBind, _TRUNCATE);
strncat_s(sqQuery, 512, ");", _TRUNCATE);
sqlite3_stmt* pStmt = NULL;
nRet = sqlite3_prepare(g_pDB, szQuery, -1, &pStmt, NULL);
if(SQLITE_OK == nRet)
{
std::list<PMY_VALUE>::iterator iter;
for(iter = plstValues->begin() ; iter != plstValues->end() ; ++iter)
{
for(iter = plstValues->begin() ; iter != plstValues->end() ; ++iter)
{
PMY_VALUE pValue = *iter;
nRet = sqlite3_reset(pStmt);
// Column 수에 맞게, 데이터 형식에 맞게 sqlite3_bind 함수를 사용하여
// 필요 값을 넣는다.
sqlite3_bind_int(pStmt, 1, pValue->xxx);
nRet = sqlite3_reset(pStmt);
// Column 수에 맞게, 데이터 형식에 맞게 sqlite3_bind 함수를 사용하여
// 필요 값을 넣는다.
sqlite3_bind_int(pStmt, 1, pValue->xxx);
sqlite3_bind_double(pStmt, 2, pValue->aaa);
sqlite3_bind_text(pStmt, 3, pValue->bbb, -1, SQLITE_STATIC);
// 완성된 쿼리 실행
nRet = sqlite3_step(pStmt);
whlie(SQLITE_ROW == nRet)
{
// 완성된 쿼리 실행
nRet = sqlite3_step(pStmt);
whlie(SQLITE_ROW == nRet)
{
nRet = sqlite_step(pStmt);
}
}
nRet = sqlite3_finalize(pStmt);
nRet = sqlite3_finalize(pStmt);
}
nRet = sqlite3_exec(g_pDB, "COMMIT;", NULL, NULL, NULL);
nRet = sqlite3_exec(g_pDB, "COMMIT;", NULL, NULL, NULL);
return 0;
}
'저장소 > VC++' 카테고리의 다른 글
[C++] DLL에서 메모리 할당, 외부에서 해제 (0) | 2009.08.20 |
---|---|
[C++] CRT Debug Heap(Memory Leak 확인 방법) (0) | 2009.08.20 |
SQLite - 쿼리 실행(어떤거 써야해?) (0) | 2009.08.13 |
[MFC] MFC에서 Thread를 사용할 때는 _beginthread 말고 AfxBeginThread를 사용해야 한다. (0) | 2009.08.07 |
[Win32] Thread 종료 확인 - GetExitCodeThread (0) | 2009.08.04 |