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);
}
댓글
댓글 쓰기