본문 바로가기

C lang

[C language] Geany편집기 -11 . c - sqlite3 DB 연동, CRUD 함수 구현

#정리 

#c - sqlite3 - c에서 db활용 
<0.sqlite3 사용 준비>
 //sudo apt install libsqlite3-dev : 패키지 설치 필요 //sudo apt install sqlite : 패키지 설치 필요
 //#include <sqlite3.h> 헤더선언 필요
<1. db open>
//sqlite3 *db; : DB연결 정보 객체는 sqlite3 타입의 포인터 변수를 활용하게 된다.
//sqlite3_open("dbpractice.db",&db); : "DB파일명(계정)"을 (개설하여)열어준다.
 - 성공하면 0 이 반환된다.
//sqlite3_stmt *stmt = NULL; : 쿼리문 컴파일 객체생성
//컴파일 설정에 -lsqlite3 옵션 추가하여 컴파일 실행
  -  build탭 >> Set Build Command >> biuld 명령어에 -lsqlite3 추가
  - $gcc -Wall -o c51sqlite3 c51sqlite3.c -lsqlite3
dbpractice.db 파일이 생성된 것을 볼 수 있다.
<2. create table>
//const char *sql_create_table = "테이블 생성 쿼리문;";  : 쿼리문 포인트 변수 생성, 수정 방지로 const사용
 - ** 쿼리문 쪽에도 ; 를 넣어줘야 한다. **
//prepare - step -  SQLITE_DONE 으로 DB통신 진행 및 결과 확인
 - sqlite3_prepare_v2(db,sql_create_table,-1,&stmt,NULL); //쿼리문 준비 - int result_create_tab = sqlite3_step(stmt); //쿼리문 통신 및 결과 확인 101 - 성공 / 21 - 실패 - printf("SQLITE_DONE: %d\n",SQLITE_DONE); //내장된 명령어 SQLITE_DONE사용 101 - 성공  / 21 - 실패
 >> 터미널에서 생성결과 확인가능 //$sqlite3 dbpractice.db ".tables"
table "test"가 생성된 것을 볼 수 있다.
<3. insert >
//const char *sql_insert = "insert 쿼리문;";  : 쿼리문 포인트 변수 생성, 수정 방지로 const사용
//prepare - step -  SQLITE_DONE 으로 DB통신 진행 및 결과 확인
 - sqlite3_prepare_v2(db,sql_insert,-1,&stmt,NULL);//쿼리문 준비
 - sqlite3_bind_text(stmt,1,"kim",-1,SQLITE_TRANSIENT);//쿼리문 1번째 값이 "kim", 문자열일 땐"-1,SQLITE_TRANSIENT" 옵션 추가
 - sqlite3_bind_int(stmt,2,33);//쿼리문 2번째 값이 33 - int result_insert = sqlite3_step(stmt);//쿼리문 통신 및 결과 확인 101 - 성공 / 21 - 실패
<7. select_one >
//const char *sql_select_one = "select one 쿼리문;"; 
//prepare - step -  SQLITE_DONE 으로 DB통신 진행 및 데이터 출력
 - sqlite3_prepare_v2(db,sql_select_one,-1,&stmt,NULL);//쿼리문 준비
 - sqlite3_bind_int(stmt,1,3);//쿼리문 1번째 값이 3
 - while(sqlite3_step(stmt) == SQLITE_ROW){//읽어들일 행이 있다면 루프 반복     
  printf("%d ",(int)sqlite3_column_int(stmt,0));//컬럼넘버와 매칭     
  printf("%s ",(char*)sqlite3_column_text(stmt,1));     
  ...DB 컬럼 수 만큼 진행... };


#c - sqlite3 - db 연동 CRUD 함수 및 콘솔 구현 
//sqlite3 *db; : db 연결 정보 객체 전역변수로 생성
//sqlite3_stmt *stmt = NULL; : 쿼리문 통신 객체 전역변수로 생성
//함수 정의 ( 실제 구현부는 main() 아래 )
 - int db_open();
 - int create();
 - int insert(char* name, int age);
 - int select_all();
 - int select_one(int num);
 - int update(char* name, int age, int num);
 - int delete(int num);
//menu console 구현
 - while (), scanf : 사용자 필요 시까지 반복 실행
 - switch - case : 필요 함수 선택 메뉴 구현

 

 

 

 

#c - sqlite3 - c에서 db활용 

<0.sqlite3 사용 준비>

 //sudo apt install libsqlite3-dev : 패키지 설치 필요
 //sudo apt install sqlite : 패키지 설치 필요

 //#include <sqlite3.h> 헤더선언 필요

<1. db open>

//sqlite3 *db; : DB연결 정보 객체는 sqlite3 타입의 포인터 변수를 활용하게 된다.

//sqlite3_open("dbpractice.db",&db); : "DB파일명(계정)"을 (개설하여)열어준다.

 - 성공하면 0 이 반환된다.

//sqlite3_stmt *stmt = NULL; : 쿼리문 컴파일 객체생성

//컴파일 설정에 -lsqlite3 옵션 추가하여 컴파일 실행

  -  build탭 >> Set Build Command >> biuld 명령어에 -lsqlite3 추가

  - $gcc -Wall -o c51sqlite3 c51sqlite3.c -lsqlite3

dbpractice.db 파일이 생성된 것을 볼 수 있다.

<2. create table>

//const char *sql_create_table = "테이블 생성 쿼리문;";  : 쿼리문 포인트 변수 생성, 수정 방지로 const사용

 - ** 쿼리문 쪽에도 ; 를 넣어줘야 한다. **

//prepare - step -  SQLITE_DONE 으로 DB통신 진행 및 결과 확인

 - sqlite3_prepare_v2(db,sql_create_table,-1,&stmt,NULL); //쿼리문 준비
 - int result_create_tab = sqlite3_step(stmt); //쿼리문 통신 및 결과 확인 101 - 성공 / 21 - 실패
 - printf("SQLITE_DONE: %d\n",SQLITE_DONE); //내장된 명령어 SQLITE_DONE사용 101 - 성공  / 21 - 실패

 >> 터미널에서 생성결과 확인가능 //$sqlite3 dbpractice.db ".tables"

table "test"가 생성된 것을 볼 수 있다.

<3. insert >

//const char *sql_insert = "insert 쿼리문;";  : 쿼리문 포인트 변수 생성, 수정 방지로 const사용

//prepare - step -  SQLITE_DONE 으로 DB통신 진행 및 결과 확인

 - sqlite3_prepare_v2(db,sql_insert,-1,&stmt,NULL);//쿼리문 준비

 - sqlite3_bind_text(stmt,1,"kim",-1,SQLITE_TRANSIENT);//쿼리문 1번째 값이 "kim", 문자열일 땐"-1,SQLITE_TRANSIENT" 옵션 추가

 - sqlite3_bind_int(stmt,2,33);//쿼리문 2번째 값이 33
 - int result_insert = sqlite3_step(stmt);//쿼리문 통신 및 결과 확인 101 - 성공 / 21 - 실패

<7. select_one >

//const char *sql_select_one = "select one 쿼리문;"; 

//prepare - step -  SQLITE_DONE 으로 DB통신 진행 및 데이터 출력

 - sqlite3_prepare_v2(db,sql_select_one,-1,&stmt,NULL);//쿼리문 준비

 - sqlite3_bind_int(stmt,1,3);//쿼리문 1번째 값이 3

 - while(sqlite3_step(stmt) == SQLITE_ROW){//읽어들일 행이 있다면 루프 반복
      printf("%d ",(int)sqlite3_column_int(stmt,0));//컬럼넘버와 매칭
      printf("%s ",(char*)sqlite3_column_text(stmt,1));
      ...DB 컬럼 수 만큼 진행... };

--예문 코드 보기--

더보기
#include <stdio.h>
#include <sqlite3.h>

int main(int argc, char **argv)
{
	//0. sqlite3 사용준비
	//sudo apt install libsqlite3-dev
	//sudo apt install sqlite3
	//#include <sqlite3.h> 
	
	//1. db open////////////////////
	sqlite3 *db;//sqlite3 타입의 포인터 변수를 활용하게 된다.
	int result_dbopen = sqlite3_open("dbpractice.db",&db);//"DB파일명(계정)"을 (개설하여)열어준다.
	printf("result_dbopen: %d\n", result_dbopen);// 0 - success
	
	//gcc -Wall -o c50sqlite3 c50sqlite3.c -lsqlite3 :-lsqlite3 옵션 추가해서 컴파일
	
	if(!result_dbopen){//if DB open successed
		printf("db open successfully!!\n");
	}
	
	sqlite3_stmt *stmt = NULL;
	////////////////////////////////
	
	//2, create table///////////////
	//쿼리문 ; 수정 방지로 const사용
	const char *sql_create_table 
			= "create table if not exists test(num integer primary key autoincrement, name text, age integer, wdate default CURRENT_TIMESTAMP);";
	
	sqlite3_prepare_v2(db,sql_create_table,-1,&stmt,NULL);//쿼리문 준비
	int result_create_tab = sqlite3_step(stmt);//쿼리문 통신 및 결과 확인 101 - 성공 / 21 - 실패
	
	printf("result_create_tab: %d\n",result_create_tab);
	printf("SQLITE_DONE: %d\n",SQLITE_DONE);//내장된 명령어 SQLITE_OK사용 101 - 성공
		if(result_create_tab == SQLITE_DONE){
				printf("create table successfully!!\n");
				//sqlite3 c50test.db ".tables"
	}
	///////////////////////////////
	
	printf("---------- insert -----------------------\n");
	//3. insert////////////////////
	const char *sql_insert
			="insert into test(name,age) values(?,?);";
			
	sqlite3_prepare_v2(db,sql_insert,-1,&stmt,NULL);//쿼리문 준비
	sqlite3_bind_text(stmt,1,"kim",-1,SQLITE_TRANSIENT);//쿼리문 1번째 값이 "kim", 문자열일 땐 "-1,SQLITE_TRANSIENT" 옵션 추가
	sqlite3_bind_int(stmt,2,33);//쿼리문 2번째 값이 33
	
	int result_insert = sqlite3_step(stmt);//쿼리문 통신 및 결과 확인 101 - 성공 / 21 - 실패
	printf("result_insert: %d\n", result_insert);
	
	if(result_insert == SQLITE_DONE){
		printf("result_insert successfully!!\n");
	}
		
	///////////////////////////////
	
	printf("---------- update -----------------------\n");
	//4. update////////////////////
	const char *sql_update
			="update test set name=?, age=? where num=?;";
			
	sqlite3_prepare_v2(db,sql_update,-1,&stmt,NULL);//쿼리문 준비
	sqlite3_bind_text(stmt,1,"lee",-1,SQLITE_TRANSIENT);//쿼리문 1번째 값이 문자열일 땐 "-1,SQLITE_TRANSIENT" 옵션 추가
	sqlite3_bind_int(stmt,2,77);//쿼리문 2번째 값이 33
	sqlite3_bind_int(stmt,3,1);//쿼리문 3번째 값이 1
	
	int result_update = sqlite3_step(stmt);//쿼리문 통신 및 결과 확인 101 - 성공 / 21 - 실패
	printf("result_update: %d\n", result_update);
	
	if(result_update == SQLITE_DONE){
		printf("result_update successfully!!\n");
	}
	///////////////////////////////
	
	printf("---------- delete -----------------------\n");
	//5. delete////////////////////
	const char *sql_delete
			="delete from test where num=?;";
			
	sqlite3_prepare_v2(db,sql_delete,-1,&stmt,NULL);//쿼리문 준비
	sqlite3_bind_int(stmt,1,2);
	
	int result_delete = sqlite3_step(stmt);//쿼리문 통신 및 결과 확인 101 - 성공 / 21 - 실패
	printf("result_delete: %d\n", result_delete);
	
	if(result_delete == SQLITE_DONE){
		printf("result_delete successfully!!\n");
	}
	///////////////////////////////
	
	printf("---------- select_all -----------------------\n");
	//6. select_all////////////////////
	const char *sql_select_all
			="select * from test;";
			
	sqlite3_prepare_v2(db,sql_select_all,-1,&stmt,NULL);//쿼리문 준비
	
	while(sqlite3_step(stmt) == SQLITE_ROW){//읽어들일 행이 있다면 루프 반복
		printf("%d ",(int)sqlite3_column_int(stmt,0));//컬럼넘버와 매칭
		printf("%s ",(char*)sqlite3_column_text(stmt,1));
		printf("%d ",(int)sqlite3_column_int(stmt,2));
		printf("%s ",(char*)sqlite3_column_text(stmt,3));
		printf("\n");
	}
	///////////////////////////////
	
	printf("---------- select_one -----------------------\n");
	//7. select_one////////////////////
	const char *sql_select_one
			="select * from test where num=?;";
			
	sqlite3_prepare_v2(db,sql_select_one,-1,&stmt,NULL);//쿼리문 준비
	sqlite3_bind_int(stmt,1,3);
	
	while(sqlite3_step(stmt) == SQLITE_ROW){//읽어들일 행이 있다면 루프 반복
		printf("%d ",(int)sqlite3_column_int(stmt,0));//컬럼넘버와 매칭
		printf("%s ",(char*)sqlite3_column_text(stmt,1));
		printf("%d ",(int)sqlite3_column_int(stmt,2));
		printf("%s ",(char*)sqlite3_column_text(stmt,3));
		printf("\n");
	}
	///////////////////////////////
	
	return 0;
}

 


 

 

#c - sqlite3 - db 연동 CRUD 함수 및 콘솔 구현 

//sqlite3 *db; : db 연결 정보 객체 전역변수로 생성
//sqlite3_stmt *stmt = NULL; : 쿼리문 통신 객체 전역변수로 생성

//함수 정의 ( 실제 구현부는 main() 아래 )
 - int db_open();
 - int create();
 - int insert(char* name, int age);
 - int select_all();
 - int select_one(int num);
 - int update(char* name, int age, int num);
 - int delete(int num);

//menu console 구현

 - while (), scanf : 사용자 필요 시까지 반복 실행

 - switch - case : 필요 함수 선택 메뉴 구현

 

 

--예문 코드 보기--

더보기
#include <stdio.h>
#include <sqlite3.h>
#include <string.h>
#include <stdlib.h>

sqlite3 *db;
sqlite3_stmt *stmt = NULL;

void db_open();
void create();
void insert(char* name, int age);
void select_all();
void select_one(int num);
void update(char* name, int age, int num);
void delete(int num);
void searchList(char* searchKey);

int main(int argc, char **argv)
{
	printf("sqlite3_fn...\n");

	db_open();
	create();
	
	static char inputKey[2];
	static int menuNum =0;

	static char searchKey[21];
	static int searchNum1 =0;
	static int searchNum2 =0;
	
	while(1){
		printf(">> press any key to show menu <<\n");
		printf("== press [x] to end menu ==\n");
		scanf("%1s",inputKey);
			if(!strcmp(inputKey,"x")){
				EXIT2 : printf("end menu...\n");
				break;
			}else{
				EXIT : printf("===<menu>===\n");
				printf("1.insert\n");
				printf("2.update\n");
				printf("3.delete\n");
				printf("4.select_one\n");
				printf("5.searchList\n");
				printf("6.exit\n");
				printf("==========\n");
				printf("input menuNum...");
				scanf("%d",&menuNum);
				switch(menuNum){
					case 6: 
						printf("6.exit\n");
						goto EXIT2;
					break;
					case 5: 
						printf("5.searchList\n");
						printf("input searchName...");
						scanf("%20s",searchKey);
						
						searchList(searchKey);
					break;
					case 4: 
						printf("4.select_one\n");
						printf("input searchNum...");
						scanf("%d",&searchNum1);
						
						select_one(searchNum1);
					break;
					case 3: 
						printf("3.delete\n");
						printf("input deleteNum...");
						scanf("%d",&searchNum1);
						
						delete(searchNum1);
					break;
					case 2: 
						printf("2.update\n");
						printf("input updateNum...");
						scanf("%d",&searchNum1);
						printf("input updateName...");
						scanf("%20s",searchKey);
						printf("input updateAge...");
						scanf("%d",&searchNum2);
						
						update(searchKey,searchNum2,searchNum1);
					break;
					case 1: 
						printf("1.insert\n");
						printf("input insertName...");
						scanf("%20s",searchKey);
						printf("input insertAge...");
						scanf("%d",&searchNum2);
						
						insert(searchKey, searchNum2);
					break;
					default:
						printf("wrong num...\n");	
						goto EXIT;//메뉴에 없는 번호가 입력되면 menu 다시 출력.
					break;
					}//end switch
			select_all();
			
			}//end if-else 
		
	}//end while
	
	return 0;
}

void db_open(){
	//1.db open////////////////

	int result_open = sqlite3_open("c50test.db",&db);//"DB파일명(계정)"을 (개설하여)열어준다.
	printf("result_open:%d\n",result_open);// 0 - success
	
	//gcc -Wall -o c50sqlite3 c50sqlite3.c -lsqlite3 :-lsqlite3 옵션 추가해서 컴파일
	
	if(!result_open){//if DB open successed
		printf("db open successfully!!\n");
	}
	///////////////////////////////
}

void create(){
	
	//2. create table/////////////
	const char *sql_create_table 
			= "create table if not exists test(num integer primary key autoincrement, name text, age integer, wdate default CURRENT_TIMESTAMP);";//쿼리문 ; 수정 방지로 const사용

	sqlite3_prepare_v2(db,sql_create_table,-1,&stmt,NULL);
	
	int result_create_tab = sqlite3_step(stmt);//생성 결과 확인 101 - 성공
	
	printf("result_create_tab: %d\n",result_create_tab);
	printf("SQLITE_DONE: %d\n",SQLITE_DONE);//내장된 명령어 SQLITE_OK사용 101 - 성공

	if(result_create_tab == SQLITE_DONE){
		printf("create table successfully!!\n");
		//sqlite3 c50test.db ".tables"
	}
	///////////////////////////////
}

void insert(char* name, int age){
	printf("---------- insert -----------------------\n");
	//3. insert/////////////
	const char *sql_insert 
			= "insert into test(name, age) values(?,?);";//쿼리문 준비
	
	sqlite3_prepare_v2(db,sql_insert,-1,&stmt,NULL);
	
	sqlite3_bind_text(stmt,1,name,-1,SQLITE_TRANSIENT);//stmt의 1번째 데이터가 "kim", 문자열일 땐 "-1,SQLITE_TRANSIENT" 옵션 추가
	sqlite3_bind_int(stmt,2,age);
	
	int result_insert = sqlite3_step(stmt);//생성 결과 확인 101 - 성공
	printf("result_insert: %d\n",result_insert);

	if(result_insert == SQLITE_DONE){
		printf("result_insert successfully!!\n");
	}
	///////////////////////////////
}

void select_all(){
	printf("--------- select_all ------------------------\n");

	//4. select_all/////////////
	const char *select_all 
			= "select * from test;";//쿼리문 준비
	
	sqlite3_prepare_v2(db,select_all,-1,&stmt,NULL);
	
	while(sqlite3_step(stmt) == SQLITE_ROW){//읽어들일 행이 있다면 루프 반복
		printf("%d ",(int)sqlite3_column_int(stmt,0));//컬럼넘버와 매칭
		printf("%s ",(char*)sqlite3_column_text(stmt,1));
		printf("%d ",(int)sqlite3_column_int(stmt,2));
		printf("%s ",(char*)sqlite3_column_text(stmt,3));
		printf("\n");
	}
	///////////////////////////////
}

void select_one(int num){
	printf("--------- select_one ------------------------\n");

	//5. select_one/////////////
	const char *select_one 
			= "select * from test where num=?;";//쿼리문 준비
	
	sqlite3_prepare_v2(db,select_one,-1,&stmt,NULL);
	sqlite3_bind_int(stmt,1,num);//첫번째 물음표에 num값 삽입
	
	while(sqlite3_step(stmt) == SQLITE_ROW){//읽어들일 행이 있다면 루프 반복
		printf("%d ",(int)sqlite3_column_int(stmt,0));//컬럼넘버와 매칭
		printf("%s ",(char*)sqlite3_column_text(stmt,1));
		printf("%d ",(int)sqlite3_column_int(stmt,2));
		printf("%s ",(char*)sqlite3_column_text(stmt,3));
		printf("\n");
	}
	///////////////////////////////
}

void update(char* name, int age, int num){
	printf("---------- update -----------------------\n");
	
	//6. update/////////////
	const char *sql_update
			= "update test set name=?, age=? where num=?;";//쿼리문 준비
	
	sqlite3_prepare_v2(db,sql_update,-1,&stmt,NULL);
	
	sqlite3_bind_text(stmt,1,name,-1,SQLITE_TRANSIENT);//stmt의 1번째 데이터가 name의 값 , 문자열일 땐 "-1,SQLITE_TRANSIENT" 옵션 추가
	sqlite3_bind_int(stmt,2,age);//2번 값 age변수 값으로 수정
	sqlite3_bind_int(stmt,3,num);
	
	int result_update = sqlite3_step(stmt);//생성 결과 확인 101 - 성공
	printf("result_update: %d\n",result_update);

	if(result_update == SQLITE_DONE){
		printf("result_update successfully!!\n");
	}
	///////////////////////////////
}

void delete(int num){
	printf("---------- delete -----------------------\n");
	
	//7. delete/////////////
	const char *sql_delete
			= "delete from test where num=?;";//쿼리문 준비
	
	sqlite3_prepare_v2(db,sql_delete,-1,&stmt,NULL);
	
	sqlite3_bind_int(stmt,1,num);
	
	int result_delete = sqlite3_step(stmt);//생성 결과 확인 101 - 성공
	printf("result_delete: %d\n",result_delete);

	if(result_delete == SQLITE_DONE){//SQLITE_DONE - 쿼리를 성공적으로 수행만 하면 101 >> 실제 삭제 여부와는 관계가 없다.
		printf("result_delete successfully!!\n");
	}
	///////////////////////////////
}

void searchList(char* searchKey){
	printf("---------- searchList -----------------------\n");
	//8. searchList/////////////
	printf("searchKey: %s\n",searchKey);
	
	//char searchName[21] = "%";//이렇게 해도 되나, 동적 할당을 통해 메모리를 아낄 수 있다.
	char *searchName = malloc(sizeof(10));
	strcpy(searchName,"%");
	strcat(searchName,searchKey);
	strcat(searchName,"%");
	printf("searchName: %s\n",searchName);
	
	const char *sql_searchList
			= "select * from test where name like ? order by num desc;";//쿼리문 준비
	
	sqlite3_prepare_v2(db,sql_searchList,-1,&stmt,NULL);
	sqlite3_bind_text(stmt,1,searchName,-1,SQLITE_TRANSIENT);
	
	while(sqlite3_step(stmt) == SQLITE_ROW){
		printf("%d ",(int)sqlite3_column_int(stmt,0));
		printf("%s ",(char*)sqlite3_column_text(stmt,1));
		printf("%d ",(int)sqlite3_column_int(stmt,2));
		printf("%s ",(char*)sqlite3_column_text(stmt,3));
		printf("\n");
	}
	
	free(searchName);
}