sqlite3数据类型和函数

sqlite3支持的数据类型:

NULL、INTEGER、REAL、TEXT、BLOB

但是,sqlite3也支持如下的数据类型

smallint 16位整数

integer 32位整数

decimal(p,s) p是精确值,s是小数位数

float 32位实数

double 64位实数

char(n) n长度字符串,不能超过254

varchar(n) 长度不固定最大字符串长度为n,n不超过4000

graphic(n) 和 char(n) 一样,但是单位是两个字符double-bytes,n不超过127(中文字)

vargraphic(n) 可变长度且最大长度为n



date 包含了年份、月份、日期

time 包含了小时、分钟、秒

timestamp 包含了年、月、日、时、分、秒、千分之一秒



sqlite3支持的函数

【1】日期函数

datetime() : 产生日期和时间

date(): 产生日期

time():产生时间

strftime():对以上3个函数产生的日期和时间进行格式化



用法实例:

1、SELECT date('2011-9-9','+1 day','+1 year'); 结果是 2010-09-10

2、SELECT datetime('now'); 当前日期和时间

3、SELECT datetime('now', 'start of month'); 本月的第一天零点,也可以设置年和日的第一天

4、SELECT datetime('now','+1 hour','-12 minute'); 当前时间加48分钟



strftime()函数可以将YYYY-MM-DD HH:MM:SS格式的日期字符串转换为其它形式的字符串

%d:天数,01-31

%f :小数形式的秒,SS.SSS

%H:小时

%j :某一天是该年的第几天,001-366

%m:月份,00-12

%M:分钟,00-59

%s:从1970到现在的秒数

%S:秒,00-59

%w:星期,0-6,0是星期天

%W:某天是该年的第几周,01-53

%Y:年,YYYY

%% 百分号



应用举例:

SELECT strftime('%Y.%m.%d %H:%M:%S','now','localtime');


二、【算术函数】



abs(X):返回绝对值

max(X,Y[,...]):返回最大值

min(X,Y,[,...]):返回最小值

random():返回随机数

round(X[,Y]): 四舍五入



三、【字符串处理函数】



length(x) :返回字符串字符个数

lower(x) :大写转小写

upper(x):小写转大写

substr(x,y,Z):截取子串

like(A,B):确定给定的字符串与指定的模式是否匹配



四、【条件判断函数、集合函数、其它函数】

*

typeof(x):返回数据的类型

last_insert_rowid():返回最后插入的数据的ID

****************

sqlite3提供了C函数接口来操作sqlite3数据库,其中有个关键数据结构 sqlite3 * 类型

1、打开数据库

int sqlite3_open(文件名,sqlite3 ); - 文件名若不存在,则会自动创建

返回SQLITE_OK表示操作正常,这些宏的定义在sqlite3.h文件中定义,看源代码会懂的更多



2、关闭数据库

int sqlite3_close(sqlite3 *);



3、SQL语句操作

int sqlite3_exec(sqlite3 ,const char sql, sqlite3_callback,void *,char errmsg);

这就是执行一条sql语句的函数

参数1:open函数得到的指针

参数2:一条sql语句,以'\0'结尾

参数3:sqlite3_callback是回调,当这条语句执行后,sqlite3会调用你提供的这个函数,回调函数要查阅资料

参数4:void 是自己提供的指针,可以传递任何指针到这里,这个参数最终会传到回调函数里面,如果不需要

传到回调函数里面,则可以设置为NULL

参数5:错误信息,当执行失败时,可以查阅这个指针,可以利用printf("%s\n",errmsg)得到一串字符串信息,

该信息表明出错的地方



通常,sqlite3_callback和void 都设置为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里传入的void *参数,通过该参数可以传入一些特殊指针
     *如类指针、结构指针,然后在这里转换成对应的类型(这里是void *类型),
     *必须强制转换成自己的类型才可用,然后操作这些数据*/

    //n_column: 该记录有多少个字段(列)

    /*char **column_value 保存着查出来的数据,实际上是个1维数组,每一个元素都是
     *char *值,是一个字段内容(用字符串表示,以\0结尾)*/

    //char **column_name 与 column_value 是对应的,表示这个字段的字段名称

    //这里不是用para参数

    printf("%=记录包含%d\n个字段",n_column);

    for(i=0;i<n_column;i++)
    {
        printf("字段名: %s ,字段值:%s\n",column_name[i],column_value[i]);
    }

    printf("\n");

    return 0;
}

int main(int , char **)
{
    sqlite3 *db;
    int result;
    char *errmsg = NULL;
    char sql[512];

    result = sqlite3_open("My.db",&db);
    if(result != SQLITE_OK)
    {
        //数据库打开失败
        return -1; 
    }

    //创建数据表
    strcpy(sql,"CREATE TABLE test(ID INTEGER PRIMARY KEY,NAME VARCHAR(32));");
    result = sqlite3_exec(db,sql,NULL,NULL,errmsg);
    if(result != SQLITE_OK)
    {
        printf("创建表失败,错误:%s\n",errmsg);
    }

    //插入记录
    strcpy(sql,"INSERT INTO test VALUES(1,'OK');");
    result = sqlite3_exec(db,sql,0,0,errmsg);
    if(result != SQLITE_OK)
    {
        printf("插入记录失败,错误:%s\n",errmsg);
    }

    //查询数据库
    strcpy(sql,"SELECT * FROM test;");
    result = sqlite3_exec(db,sql,LoadMyInfo,NULL,errmsg);

    sqlite3_close(db);

    return 0;
}

以上是通过回调查询数据库,如果该函数在C++中,就要将其声明成static类型,因为C++

成员函数隐藏了一个参数:this,C++调用类的成员函数的时候,隐含把类指针当函数的第

一个参数传递进去,就与上面的sqlite回调函数参数不符



除了使用回调来查询,还可以使用非回调的查询,通过sqlite3_get_table函数做到

int sqlite3_get_table(sqlite3,const char sql,char resultp,int nrow,int *ncolumn,char errmsg);

参数3:resultp 是一维数组,第一行是字段名称,跟着是每个字段的值

参数4:查询共多少条记录

参数5:查询共多少个字段



操作实例如下:

int main(int ,char **)
{
    sqlite3 *db;
    int result;
    char *errmsg = NULL;

    char **dbResult;
    int nRow,nColumn;
    int i,j;
    int index;

    char sql[512];

    result = sqlite3_open("My.db",&db);
    if(result != SQLITE_OK)
    {
        return -1;
    }

    result = sqlite3_get_table(db,sql,&dbResult,&nRow,&nColumn,&errmsg);
    //查询成功
    if(SQLITE_OK == result) 
    {
        //dbResult第一行是字段名称,从nColumn索引开始时真正的数据
        index = nColumn;
        printf("查询到%d记录\n",nRow);

        for(i=0;i<nRow;i++)
        {
            for(j=0;j<nColumn;j++)
            {
                printf("字段名称:%s,字段值:%s\n",dbResult[j],dbResult[index]);
                index++;
            }
            printf("\n");
        }
    }

    //释放char**查询结果
    sqlite3_free_table(dbResult); 

    sqlite3_close(db);

    return 0;
}

上述使用的方法适用于大多数数据库需求,但是不能适用于二进制数据,操作二进制数据方法需要用到一个数据类型sqlite3_stmt *,该数据类型记录了一个"sql语句",这里的sql语句是解析后的,用sqlite自己标记记录的内部数据结构,并不是我们熟悉的sql语句



数据插入到 sqlite3_stmt结构里可不能直接memcpy,也不能像std::string那样用+号,必须用sqlite提供的

函数来插入。



假设有创建一张表如下

CREATE TABLE test2(ID INTEGER,file_content BLOB)



首先声明 sqlite3_stmt stat; 然后将一个sql语句解析到stat结构里去

sqlite3_prepare(db,"INSERT INTO test2(ID,file_content) VALUES(10,?)",-1,&stat,0);

这里sql语句中有个?号,在该函数里,?表示一个未定的值

参数3:表示前面sql语句的长度,如果小于0,sqlite会自动计算它的长度

参数4:sqlite3_stat指针的指针,解析后的sql语句就放在该结构里

参数5:一般设为0



返回值为SQLITE_OK且stat不为NULL,表示成功,当prepare成功后,开始查询数据

int result = sqlite3_step(stat);

该值返回SQLITE_ROW 表示成功



可以循环执行sqlite3_step函数,一次step查询出一条记录,直到返回值不为SQLITE_ROW

然后开始获取第一个字段:ID值,ID是个整数,使用如下操作

int id = sqlite3_column_int(stat,0); //0表示第1字段

下面获取file_content的值,因为file_content是二进制,因此需要得到它的指针,还有长度

const void * pFileContent = sqlite3_column_blob(stat,1);

int len = sqlite3_column_bytes(stat,1);

把 pFileContent内容保存后,要释放sqlite3_stmt结构

sqlite3_finalize(stat);



如果需要重复使用 sqlite3_prepare解析好的sqlite3_stmt结构,使用 sqlite3_reset函数

result = sqlite3_reset(stat);

这样,stat结构又成为sqlite3_prepare完成时的状态



sqlite 数据库事务处理

*

如果需要同步删除很多数据,可以将它们做成一个统一的事务,通常sqlite3_exec就是一次事务,假设要删除1W条记录,sqlite就做了1W次,开始事务->删除数据->提交事务,这个操作很慢,我们可以将同类操作作成一个事物,如果操作错误,还可以回滚事务



事务的操作没有特别的接口函数,只是普通的sql语句

int result;

result = sqlite3_exec(db,"begin transtraction",0,0,&zErrorMsg);

result = sqlite3_exec(db,"commit transtraction",0,0,&zErrorMsg);

result = sqlite3_exec(db,"rollback transtraction",0,0,&zErrorMsg);



sqlite3 错误编码如下:

define SQLITE_OK 0 / Successful result /

#define SQLITE_ERROR 1 / SQL error or missing database /

#define SQLITE_INTERNAL 2 / An internal logic error in SQLite /

#define SQLITE_PERM 3 / Access permission denied /

#define SQLITE_ABORT 4 / Callback routine requested an abort /

#define SQLITE_BUSY 5 / The database file is locked /

#define SQLITE_LOCKED 6 / A table in the database is locked /

#define SQLITE_NOMEM 7 / A malloc() failed /

#define SQLITE_READONLY 8 / Attempt to write a readonly database /

#define SQLITE_INTERRUPT 9 / Operation terminated by sqlite_interrupt() /

#define SQLITE_IOERR 10 / Some kind of disk I/O error occurred /

#define SQLITE_CORRUPT 11 / The database disk image is malformed /

#define SQLITE_NOTFOUND 12 / (Internal Only) Table or record not found /

#define SQLITE_FULL 13 / Insertion failed because database is full /

#define SQLITE_CANTOPEN 14 / Unable to open the database file /

#define SQLITE_PROTOCOL 15 / Database lock protocol error /

#define SQLITE_EMPTY 16 / (Internal Only) Database table is empty /

#define SQLITE_SCHEMA 17 / The database schema changed /

#define SQLITE_TOOBIG 18 / Too much data for one row of a table /

#define SQLITE_CONSTRAINT 19 / Abort due to contraint violation /

#define SQLITE_MISMATCH 20 / Data type mismatch /

#define SQLITE_MISUSE 21 / Library used incorrectly /

#define SQLITE_NOLFS 22 / Uses OS features not supported on host /

#define SQLITE_AUTH 23 / Authorization denied /

#define SQLITE_ROW 100 / sqlite_step() has another row ready /

#define SQLITE_DONE 101 / sqlite_step() has finished executing /

转 : http://blog.csdn.net/xiaomt_rush/article/details/6766482
原文链接: https://www.cnblogs.com/622698abc/archive/2013/04/10/3012143.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/84043

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午9:23
下一篇 2023年2月9日 下午9:24

相关推荐