SQL을 사용한 SQLite 예제 코드

본 글은 SQL을 사용한 SQLite 예제 C 소스 코드를 싣고 있다. 

 

SQLite는 C언어로 구현된 SQL 데이터 베이스 엔진이다. 소스 코드도 공개되어 있고, 여러 플랫폼에서 사용 가능하며, 작고, 빠른 장점이 있다고 한다.  SQLite 홈페이지에서 소스와 바이너리를 다운로드 할 수 있으며, 본 글의 예제에서는 C 소스 코드를 다운받아 사용하였다. 

sqlite-amalgamation-3320000.zip
프로젝트에 sqlite3.c을 추가 하여 빌드하였으며, 헤더파일은 sqlite3.h을 사용하였다.

SQL 쿼리는 sqlite3_exec함수를 사용하여 실행할 수 있다. 두번째 파라메터에 SQL 쿼리를 넣으면 된다.

db파일 열기/닫기

 #include "sqlite3.h"

void close_db(sqlite3* db)
{
if (db)
{
sqlite3_close(db);
db = NULL;
}
}

sqlite3* open_db()
{
sqlite3 *db = NULL;

if (sqlite3_open("test.db", &db) != SQLITE_OK)
{
_trace(TEXT("Can't open database: %s\r\n"), sqlite3_errmsg(db));
if (db) close_db(db);
return NULL;
}

return db;
}


db 테이블 만들기


예제는 아래와 같이 과일 종류와 가격, 재고수량을 저장하는 테이블을 만들었다.

FRUITS_KEEPER
 FRUIT_TYPE  PRICE  STOCKS
     

int create_table(sqlite3* db)
{
char *zErrMsg = 0;
char *create_query = "CREATE TABLE FRUITS_KEEPER (FRUIT_TYPE TEXT PRIMARY KEY NOT NULL, PRICE TEXT NOT NULL, STOCKS TEXT NOT NULL);";

if (!db) return -1;

if (sqlite3_exec(db, create_query, NULL, NULL, &zErrMsg) != SQLITE_OK)
{
_trace(TEXT("[create_table] CREATE: %S\r\n"), zErrMsg);
sqlite3_free(zErrMsg);
return -1;
}

_trace(TEXT("[create_table] done \r\n"));

return 0;
}


insert / update

db에 추가하고 업데이트하는 루틴은 아래와 같다.

int put_db(sqlite3* db, char *kinds, int price, int stocks)
{
char *zErrMsg = 0;
char query[128] = { 0, };

if (!db || !kinds || !price || !stocks) return -1;

sprintf_s(query, 128, "INSERT INTO FRUITS_KEEPER (FRUIT_TYPE,PRICE,STOCKS) VALUES ('%s', '%d', '%d');", kinds, price, stocks);

if (sqlite3_exec(db, query, NULL, 0, &zErrMsg) != SQLITE_OK)
{
_trace(TEXT("[put_db] INSERT : %S\r\n"), zErrMsg);
sqlite3_free(zErrMsg);
return -1;
}

return 0;
}

int update_db(sqlite3* db, char *kinds, int price, int stock)
{
char *zErrMsg = 0;
char query[128] = { 0, };

if (!db || !kinds) return -1;

sprintf_s(query, 128, "UPDATE FRUITS_KEEPER SET PRICE = '%d' WHERE FRUIT_TYPE ='%s';\0", price, kinds);

if (sqlite3_exec(db, query, NULL, 0, &zErrMsg) != SQLITE_OK)
{
_trace(TEXT("[update_db] UPDATE : %S\r\n"), zErrMsg);
sqlite3_free(zErrMsg);
return -1;
}

sprintf_s(query, 128, "UPDATE FRUITS_KEEPER SET STOCKS = '%d' WHERE FRUIT_TYPE ='%s';\0", stock, kinds);

if (sqlite3_exec(db, query, NULL, 0, &zErrMsg) != SQLITE_OK)
{
_trace(TEXT("[update_db] UPDATE : %S\r\n"), zErrMsg);
sqlite3_free(zErrMsg);
return -1;
}

return 0;
}


db 검색 


SELECT 쿼리를 사용해 db를 검색할 수 있다. 이때 검색된 내용은 callback을 통해 전달된다. Search_cb에서 데이터 구조체에 검색된 내용을 저장하도록 했다.

typedef struct _search_cb_data_t
{
char kinds[32];
int found;
int price;
int stock;
}search_cb_data_t;


static int search_cb(void *data, int argc, char **argv, char **azColName)
{
search_cb_data_t *user_data = (search_cb_data_t*)data;

if (user_data)
{
if (argc == 3 && strcmp(azColName[0], "FRUIT_TYPE") == 0
&& argv[0] && strcmp(argv[0], user_data->kinds) == 0
&& strcmp(azColName[1], "PRICE") == 0
&& strcmp(azColName[2], "STOCKS") == 0)
{
user_data->found = 1;
if (argv[1]) user_data->price = atoi(argv[1]);
if (argv[2]) user_data->stock = atoi(argv[2]);
}
}

return 0;
}


int search_db(sqlite3* db, char *kinds, int *price, int *stock)
{
char *zErrMsg = 0;
search_cb_data_t user_data = { 0, };
char query[128] = { 0, };

if (!db || !kinds) return -1;

memset(&user_data, 0, sizeof(search_cb_data_t));

sprintf_s(user_data.kinds, 32, "%s", kinds);
sprintf_s(query, 128, "SELECT * FROM FRUITS_KEEPER WHERE FRUIT_TYPE LIKE '%s';", kinds);

if (sqlite3_exec(db, query, search_cb, (void*)&user_data, &zErrMsg) != SQLITE_OK)
{
// not found...
_trace(TEXT("[search_db] SELECT : %S\n"), zErrMsg);
sqlite3_free(zErrMsg);
return -1;
}

if (user_data.found)
{
if (price) *price = user_data.price;
if (stock) *stock = user_data.stock;
return 0;
}

return -1;
}


테스트 코드와 실행 결과


void sqlite_test()
{
int price = 0;
int stock = 0;

sqlite3 *db = open_db();

create_table(db);

_trace(TEXT("put db\r\n"));

if (search_db(db, "apple", NULL, NULL) != 0) put_db(db, "apple", 1500, 100);
if (search_db(db, "orange", NULL, NULL) != 0) put_db(db, "orange", 1000, 200);
if (search_db(db, "watermelon", NULL, NULL) != 0) put_db(db, "watermelon", 9000, 80);
if (search_db(db, "peach", NULL, NULL) != 0) put_db(db, "peach", 1200, 200);


search_db(db, "apple", &price, &stock);
_trace(TEXT("apple price %d stock %d\r\n"), price, stock);
search_db(db, "orange", &price, &stock);
_trace(TEXT("orange price %d stock %d\r\n"), price, stock);
search_db(db, "watermelon", &price, &stock);
_trace(TEXT("watermelon price %d stock %d\r\n"), price, stock);
search_db(db, "peach", &price, &stock);
_trace(TEXT("peach price %d stock %d\r\n"), price, stock);

/*
*/
_trace(TEXT("update db\r\n"));

update_db(db, "apple", 1500, 50);
update_db(db, "orange", 900, 200);
update_db(db, "watermelon", 9000, 100);
update_db(db, "peach", 1200, 100);

search_db(db, "apple", &price, &stock);
_trace(TEXT("apple price %d stock %d\r\n"), price, stock);
search_db(db, "orange", &price, &stock);
_trace(TEXT("orange price %d stock %d\r\n"), price, stock);
search_db(db, "watermelon", &price, &stock);
_trace(TEXT("watermelon price %d stock %d\r\n"), price, stock);
search_db(db, "peach", &price, &stock);
_trace(TEXT("peach price %d stock %d\r\n"), price, stock);

close_db(db);
}

 


댓글

이 블로그의 인기 게시물

간단한 cfar 알고리즘에 대해

windows에서 간단하게 크롬캐스트(Chromecast)를 통해 윈도우 화면 미러링 방법

간단한 칼만 필터(Kalman Filter) 소스 코드와 사용 예제

안드로이드(android) 전체 화면 시계 앱(clock app) 예제 코드

mkfs.fat Device or resource busy 에러 해결법