直接上代碼
mydll.cpp
#include "sqlite3.h"
#include <stdio.h>
#define MYDLL_EXPORTS
#include "mydll.h"
#include <iostream>
using namespace std;
#pragma comment(lib, "sqlite3.lib")
sqlite3 *db = NULL; //定義數據庫連接
const char *errMsg = 0; //定義錯誤信息
char *zerrMsg = 0; //定義錯誤信息
//打開數據庫
int open_db()
{
int rc = sqlite3_open("E:/project/tb3/sqlite/tb/sqlit_tb/sqlit_tb/sqlitej.db",&db); //打開數據庫
if(rc != SQLITE_OK) //數據庫打開失敗
{
errMsg = sqlite3_errmsg(db); //獲取錯誤信息
cout<<errMsg<<endl;
sqlite3_close(db); //關閉數據庫連接
return -1;
}
cout<<"open database successfully!"<<endl;
return 0;
}
//創建表
int create_table()
{
if(open_db() != 0)
{
open_db();
}
char *sql = "create table tab(id int primary key ,name varchar(20) ,age int)";
/**
//執行創建表語句 參數一:數據庫連接 參數二:需要執行的SQL語句 參數三:回調函數 參數四:回調函數的第一個參數 參數五:錯誤消息。
回調函數的格式如下:
int sqlite_callback(
void* pvoid, 由 sqlite3_exec() 的第四個參數傳遞而來
int argc, 表的列數
char** argv, 指向查詢結果的指針數組, 可以由 sqlite3_column_text() 得到
char** col 指向表頭名的指針數組, 可以由 sqlite3_column_name() 得到
);
說明:
sqlite3_exec() 的回調函數必須按照此格式, 當然形參的名字任意.
如果某列的數據類型不是char*, 則可以對結果執行相關的轉換, 如:用atoi()把結果轉換爲整數(integer), 如果是二進制數據, 則可以直接強制類型轉換, 如:(void*)argv[i].
該回調函數有兩種返回值類型.
1.返回零:sqlite3_exec() 將繼續執行查詢.
2.返回非零:sqlite3_exec()將立即中斷查詢, 且 sqlite3_exec() 將返回 SQLITE_ABORT.
*/
int rc = sqlite3_exec(db,sql,NULL,NULL,&zerrMsg);
if(rc != SQLITE_OK)
{
errMsg = sqlite3_errmsg(db);
cout<<errMsg<<endl; // cout<<zerrMsg<<endl;
sqlite3_close(db);
return -1;
}
cout<<"創建表成功!"<<endl;
return 0;
}
//刪除表
int drop_table()
{
if(open_db() != 0)
{
open_db();
}
char *sql = "drop table tab";
int rc = sqlite3_exec(db,sql,NULL,NULL,&zerrMsg);
if(rc != SQLITE_OK)
{
errMsg = sqlite3_errmsg(db);
cout<<errMsg<<endl; // cout<<zerrMsg<<endl;
sqlite3_close(db);
return -1;
}
cout << "delete success" << endl;
return 0;
}
//數據添加
int insert_data(int id,char *name,int age)
{
if(open_db() != 0)
{
open_db();
}
sqlite3_stmt *stmt = NULL; //準備語句對象
char *sql = "insert into tab(id,name,age) values(?,?,?)";
/**
參數一:數據庫連接 參數二:需要執行的SQL語句 參數三:SQL的長度 參數四:準備語句對象
參數三:如果nByte小於0,則函數取出zSql中從開始到第一個0終止符的內容;如果nByte不是負的,那麼它就是這個函數能從zSql中讀取的字節數的最大值。如果nBytes非負,zSql在第一次遇見’/000/或’u000’的時候終止
參數五:上面提到zSql在遇見終止符或者是達到設定的nByte之後結束,假如zSql還有剩餘的內容,那麼這些剩餘的內容被存放到pZTail中,不包括終止符
*/
int rc = sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,NULL);
if(rc != SQLITE_OK)
{
errMsg = sqlite3_errmsg(db);
cout<<errMsg<<endl;
if(stmt)
{
sqlite3_finalize(stmt);
}
sqlite3_close(db);
return -1;
}
sqlite3_bind_int(stmt,1,id);
//參數一:準備語句對象 參數二:序號(從1開始)參數三:字符串值 參數四:字符串長度 參數五:函數指針,SQLITE3執行完操作後回調此函數,通常用於釋放字符串佔用的內存。(這個函數指針參數具體怎麼使用,我現在還不清楚
sqlite3_bind_text(stmt,2,name,strlen(name),NULL);
sqlite3_bind_int(stmt,3,age);
/**
statement準備好了以後,就是操作的執行了
它的返回值相對有些特殊。返回SQLITE_BUSY表示暫時無法執行操作,SQLITE_DONE表示操作執行完畢(執行update, delete, insert等語句),
SQLITE_ROW表示執行完畢並且有返回(執行select語句時)。當返回值爲SQLITE_ROW時,我們需要對查詢結果進行處理,
SQLITE3提供sqlite3_column_*系列函數。
*/
if(sqlite3_step(stmt) != SQLITE_DONE)
{
sqlite3_finalize(stmt);
sqlite3_close(db);
return -1;
}
cout << "add success" << endl;
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
//數據查詢 根據id唯一性查詢
int search_data(int id)
{
if(open_db() != 0)
{
open_db();
}
char *sql = "select * from tab where id = ?";
sqlite3_stmt *stmt = NULL;
int rc = sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,NULL);
if(rc != SQLITE_OK)
{
errMsg = sqlite3_errmsg(db);
cout<<errMsg<<endl;
if(stmt)
{
sqlite3_finalize(stmt);
}
sqlite3_close(db);
return -1;
}
sqlite3_bind_int(stmt,1,id);
int nColumn = sqlite3_column_count(stmt); //獲取數據庫表的列數
int type; //表字段所對應的類型
rc = sqlite3_step(stmt);
if(rc == SQLITE_ROW)
{
for(int i=0;i<nColumn;i++)
{
type = sqlite3_column_type(stmt,i);
if(type == SQLITE_INTEGER)
{
cout<<sqlite3_column_name(stmt,i)<<"\t"<<sqlite3_column_int(stmt,i)<<endl;
}
if(type == SQLITE_TEXT)
{
cout<<sqlite3_column_name(stmt,i)<<"\t"<<sqlite3_column_text(stmt,i)<<endl;
}
else if(type == SQLITE_NULL)
{
cout<<"no value"<<endl;
}
}
}
else if(rc == SQLITE_DONE)
{
cout<<"select finish!"<<endl;
}
else
{
cout<<"select fail"<<endl;
sqlite3_finalize(stmt);
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
//數據查詢 根據姓名批量查詢
int search_data(char *name)
{
if(open_db() != 0)
{
open_db();
}
char *sql = "select * from tab where name = ?";
sqlite3_stmt *stmt = NULL;
int rc = sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,NULL);
if(rc != SQLITE_OK)
{
errMsg = sqlite3_errmsg(db);
cout<<errMsg<<endl;
if(stmt)
{
sqlite3_finalize(stmt);
}
sqlite3_close(db);
return -1;
}
sqlite3_bind_text(stmt,1,name,strlen(name),NULL);
int nColumn = sqlite3_column_count(stmt);
int type;
rc = sqlite3_step(stmt);//如果是select語句,且有還有記錄,則應該返回SQLITE_ROW
while(true) {
if(rc == SQLITE_ROW)
{
cout<<"--------------"<<endl;
for(int i=0;i<nColumn;i++)
{
type = sqlite3_column_type(stmt,i);
if(type == SQLITE_INTEGER)
{
cout<<sqlite3_column_name(stmt,i)<<"\t"<< sqlite3_column_int(stmt,i)<<endl;
}
if(type == SQLITE_TEXT)
{
cout<<sqlite3_column_name(stmt,i)<<"\t"<< sqlite3_column_text(stmt,i)<<endl;
}
else if(type == SQLITE_NULL)
{
cout<<"no value"<<endl;
}
}
}
else if(rc == SQLITE_DONE)
{
cout<<"select finish!"<<endl;
}
else
{
cout<<"select fail"<<endl;
sqlite3_finalize(stmt);
}
if (sqlite3_step(stmt) != SQLITE_ROW)
break;
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
//刪除數據
int delete_data(int age)
{
if(open_db() != 0)
{
open_db();
}
char *sql = "delete from tab where age = ?";
sqlite3_stmt *stmt = NULL;
int rc = sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,NULL);
if(rc != SQLITE_OK)
{
errMsg = sqlite3_errmsg(db);
cout<<errMsg<<endl;
if(stmt)
{
sqlite3_finalize(stmt);
}
sqlite3_close(db);
return -1;
}
sqlite3_bind_int(stmt,1,age);
rc = sqlite3_step(stmt);//如果是update, delete, insert等語句,正常應該返回 SQLITE_DONE
if(rc == SQLITE_DONE)//SQLITE_DONE意味着已成功完成執行該語句
{
cout<<"刪除數據成功"<<endl;
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
int callback(void *data, int argc, char **argv, char **azColName){
int i;
fprintf(stderr, "%s: ", (const char*)data);
for(i=0; i<argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
//數據查詢
int All_Data()
{
char *sql;
const char* data = "Callback function called";
if(open_db() != 0)
{
open_db();
}
sql = "SELECT * from tab";
/* Execute SQL statement */
int rc = sqlite3_exec(db, sql, callback, (void*)data, &zerrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zerrMsg);
sqlite3_free(zerrMsg);
}else{
fprintf(stdout, "Operation done successfully\n");
}
sqlite3_close(db);
return 0;
}
mydll.h
#pragma once
#ifndef _MYDLL_H
#define _MYDLL_H
#ifdef MYDLL-EXPORTS
#define MYDLL _declspec(dllexport)
#else
#define MYDLL _declspec(dllimport)
#endif
int MYDLL open_db();
int MYDLL create_table();
int MYDLL drop_table();
int MYDLL insert_data(int id, char *name, int age);
int MYDLL search_data(int id);
int MYDLL search_data(char *name);
int MYDLL All_Data();
int MYDLL delete_data(int age);
#endif
app.cpp
#include <iostream>
#include <stdio.h>
#include "mydll.h"
//使用庫
#pragma comment(lib,"Dll_tb.lib")
using namespace std;
int main()
{
open_db();
create_table();
//drop_table();
insert_data(7, (char*)"ete",42);
//search_data(2);
All_Data();
//delete_data(21);
return 0;
}
工程代碼下載鏈接: