在vc中使用sqlite3数据库

一,
在DOS命令行下:
PATH = C:\Program Files\Microsoft Visual Studio 10.0\VC\bin;%PATH%
PATH = C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE;%PATH%
LIB /DEF:sqlite3.def /machine:IX86

新建一个mysqlite工程,把自己生成的.lib拷到工程下,当然还有.dll。
在主文件中:
#include "sqlite3.h"
#pragma comment(lib, "sqlite3.lib")

////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

二,
Sqlite3支持的数据类型

NULL
INTEGER
REAL
TEXT
BLOB
但实际上,sqlite3也接受如下的数据类型:
smallint 16 位元的整数。
interger 32 位元的整数。
decimal(p,s) p 精确值和 s 大小的十进位整数,精确值p是指全部有几个数(digits)大小值,s是指小数点後有几位数。如果没有特别指定,则系统会设为 p=5; s=0 。
float   32位元的实数。
double   64位元的实数。
char(n)   n 长度的字串,n不能超过 254。
varchar(n) 长度不固定且其最大长度为 n 的字串,n不能超过 4000。
graphic(n) 和 char(n) 一样,不过其单位是两个字元 double-bytes, n不能超过127。这个形态是为了支援两个字元长度的字体,例如中文字。
vargraphic(n) 可变长度且其最大长度为 n 的双字元字串,n不能超过 2000
date   包含了 年份、月份、日期。
time   包含了 小时、分钟、秒。
timestamp 包含了 年、月、日、时、分、秒、千分之一秒。


//////////////////////////////////////////////////////////////////////////////

三,
1,打开一个数据库,如果改数据库不存在,则创建一个名字为filename的数据库文件
int sqlite3_open(
  const char *filename,  
  sqlite3 **ppDb          
);

2,查询操作
int sqlite3_exec(
  sqlite3*,                                  
  const char *sql,                          
  int (*callback)(void*,int,char**,char**),  
  void *,                                    
  char **errmsg                              
);
第1个参数不再说了,是前面open函数得到的指针。叫关键数据结构。
第2个参数const char *sql 是一条 sql 语句,以\0结尾。
第3个参数sqlite3_callback 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。
第4个参数void*是你所提供的指针,传给回调函数的指针参。
第5个参数char**errmsg是错误信息。sqlite3里面有很多固定的错误信息。执行sqlite3_exec之后,执行失败时可以查阅这个指针(直接printf(“%s\n”,errmsg))得到一串字符串信息,这串信息告诉你错在什么地方。sqlite3_exec函数通过修改你传入的指针的指针,把你提供的指针指向错误提示信息,这样sqlite3_exec函数外面就可以通过这个char*得到具体错误提示。
说明:通常,sqlite3_callback和它后面的void*这两个位置都可以填NULL。填NULL表示你不需要回调。若做insert、delete操作,就没有必要使用回调。而select时,就要使用回调,因为sqlite3把数据查出来,得通过回调告诉你查出了什么数据。

typedef int (*sqlite3_callback)(void*,int,char**, char**);
你的回调函数必须定义成上面这个函数的类型。下面给个简单的例子:
// sqlite 每查到一条记录,就调用一次这个回调
int LoadMyInfo( void * para, int n_column, char ** column_value, char ** column_name )
{
//para是你在 sqlite3_exec 里传入的 void * 参数
//通过para参数,你可以传入一些特殊的指针(比如类指针、结构指针),然后在这里面强制转换成对应的类型(这里面是void*类型,必须强制转换成你的类型才可用)。然后操作这些数据
//n_column是这一条记录有多少个字段 (即这条记录有多少列)
//char ** column_value 是个关键值,查出来的数据都保存在这里,它实际上是个1维数组(不要以为是2维数组),每一个元素都是一个 char * 值,是一个字段内容(用字符串来表示,以\0结尾)
//char ** column_name 跟 column_value是对应的,表示这个字段的字段名称
...}

不用回调函数的查询
int sqlite3_get_table(
  sqlite3 *db,          
  const char *zSql,    
  char ***pazResult,    
  int *pnRow,          
  int *pnColumn,        
  char **pzErrmsg      
);
//pazResult指向查询结果
//dbResult 的字段值是连续的,从第0索引到第 nColumn - 1索引都是字段名称,从第 nColumn 索引开始,后面都是字段值,它把一个二维的表(传统的行列表示法)用一个扁平的形式来表示
//pnRow查询出多少条记录(即查出多少行)。
//pnColumn多少个字段(多少列)

void sqlite3_free_table(char **result);//不论数据库查询是否成功,都释放 char** 查询结果,使用 sqlite 提供的功能来释放

3,关闭数据库
sqlite3_close(db);

////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
四,
// 连接数据库
ret = sqlite3_open("./liuhan.db", &db);
if ( ret != SQLITE_OK )
{
fprintf(stderr, "无法打开数据库: %s", sqlite3_errmsg(db));
return(1);
}

char **dbResult;
int nRow, nColumn;
//查找 myAddress 表是否已有
sqlite3_get_table(db, "SELECT * FROM sqlite_master where type='table' and name='myAddress'", &dbResult, &nRow, &nColumn, NULL);
if(nRow > 0 )
{
printf( "此表存在\n" );
// 查询数据表
const char * sSQL3 = "select * from myAddress;";
////////////////////////////////////////////////////////////////////
////1,回调查询
//sqlite3_exec( db, sSQL3, _sql_callback, 0, &pErrMsg);
////////////////////////////////////////////////////////////////////
////2,不用回调函数的查询
char **dbResult1;
if(SQLITE_OK == sqlite3_get_table( db, sSQL3, &dbResult1, &nRow, &nColumn, &pErrMsg ));
{
//dbResult1 前面第一行数据是字段名称,从 nColumn 索引开始才是真正的数据
// dbResult1 的字段值是连续的,从第0索引到第 nColumn - 1索引都是字段名称,从第 nColumn 索引开始,
//后面都是字段值,它把一个二维的表(传统的行列表示法)用一个扁平的形式来表示
int index = nColumn;
for(int i = 1; i <= nRow ; i++)
{
printf( "第 %d 条记录\n", i );
//for(int j = 0 ; j < nColumn; j++)
//{
//printf( "字段名:%s 字段值:%s\n", dbResult1[j],dbResult1[index++] ); //}
myAddress.ip = dbResult[index++];
myAddress.latitude = atof(dbResult[index++]);
myAddress.longitude = atof(dbResult[index++]);
myAddress.UID = atoi(dbResult[index++]);
}
}
sqlite3_free_table( dbResult1 );
//不论数据库查询是否成功,都释放 char** 查询结果,使用 sqlite 提供的功能来释放
}

else 
{
printf( "此表不存在\n" );
// 执行建表SQL
const char * sSQL1 = "create table myAddress(ip varchar(20),latitude double, longitude double , uid integer PRIMARY KEY );";
ret = sqlite3_exec( db, sSQL1, 0, 0, &pErrMsg );
if ( ret != SQLITE_OK )
{
fprintf(stderr, "SQL error: %s\n", pErrMsg);
sqlite3_free(pErrMsg);
}

// 执行插入记录SQL
int myId = 666666;
char *sSQL2 = new char[100];
memset(sSQL2,0,100);
sprintf(sSQL2, "insert into myAddress values('%s', %f ,%f ,%d);",
ip_location->ip,ip_location->latitude,ip_location->longitude,myId);

if ( SQLITE_OK != sqlite3_exec( db, sSQL2, 0, 0, &pErrMsg) )
{
fprintf(stderr, "SQL error: %s\n", pErrMsg);
sqlite3_free(pErrMsg);
}
delete[] sSQL2;
}
sqlite3_free_table( dbResult );


///////////////////////////////////////////////////////////////////
    // 关闭数据库
    sqlite3_close(db);
    db = 0;

你可能感兴趣的:(MFC)