SQLite3的绑定函数族使用与其注意事项详解_SQLite

来源:脚本之家  责任编辑:小易  

一.使用流程要使用sqlite,需要从sqlite官网下载到三个文件,分别为sqlite3.lib,sqlite3.dll,sqlite3.h,然后再在自己的工程中配置好头文件和库文件,同时将dll文件放到当前目录下,就完成配置可以使用sqlite了。使用的过程根据使用的函数大致分为如下几个过程:sqlite3_open()sqlite3_prepare()sqlite3_step()sqlite3_column()sqlite3_finalize()sqlite3_close()这几个过程是概念上的说法,而不完全是程序运行的过程,如sqlite3_column()表示的是对查询获得一行里面的数据的列的各个操作统称,实际上在sqlite中并不存在这个函数。1.sqlite3_open():打开数据库在操作数据库之前,首先要打开数据库。这个函数打开一个sqlite数据库文件的连接并且返回一个数据库连接对象。这个操作同时程序中的第一个调用的 sqlite函数,同时也是其他sqlite api的先决条件。许多的sqlite接口函数都需要一个数据库连接对象的指针作为它们的第一个参数。函数定义const char*filename,/*Database filename(UTF-8)*/sqlite3*ppDb/*OUT:SQLite db handle*/const void*filename,/*Database filename(UTF-16)*/sqlite3*ppDb/*OUT:SQLite db handle*/const char*filename,/*Database filename(UTF-8)*/sqlite3*ppDb,/*OUT:SQLite db handle*/int flags,/*Flags*/const char*zVfs/*Name of VFS module to use*/说明:假如这个要被打开的数据文件不存在,则一个同名的数据库文件将被创建。如果使用sqlite3_open和sqlite3_open_v2的话,数据库将采用UTF-8的编码方式,sqlite3_open16采用UTF-16的编码方式返回值:如果sqlite数据库被成功打开(或创建),将会返回SQLITE_OK,否则将会返回错误码。Sqlite3_errmsg()或者sqlite3_errmsg16可以用于获得数据库打开错误码的英文描述,这两个函数定义为:const char*sqlite3_errmsg(sqlite3*);const void*sqlite3_errmsg16(sqlite3*);参数说明:filename:需要被打开的数据库文件的文件名,在sqlite3_open和sqlite3_open_v2中这个参数采用UTF-8编码,而在sqlite3_open16中则采用UTF-16编码ppDb:一个数据库连接句柄被返回到这个参数,即使发生错误。唯一的一场是如果sqlite不能分配内存来存放sqlite对象,ppDb将会被返回一个NULL值。flags:作为数据库连接的额外控制的参数,可以是SQLITE_OPEN_READONLY,SQLITE_OPEN_READWRITE和 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE中的一个,用于控制数据库的打开方式,可以和SQLITE_OPEN_NOMUTEX,SQLITE_OPEN_FULLMUTEX,SQLITE_OPEN_SHAREDCACHE,以及SQLITE_OPEN_PRIVATECACHE结合使用,具体的详细情况可以查阅文档2.Sqlite3_prepare()这个函数将sql文本转换成一个准备语句(prepared statement)对象,同时返回这个对象的指针。这个接口需要一个数据库连接指针以及一个要准备的包含SQL语句的文本。它实际上并不执行(evaluate)这个SQL语句,它仅仅为执行准备这个sql语句函数定义(仅列出UTF-8的)sqlite3*db,/*Database handle*/const char*zSql,/*SQL statement,UTF-8 encoded*/int nByte,/*Maximum length of zSql in bytes.*/sqlite3_stmt*ppStmt,/*OUT:Statement handle*/const char*pzTail/*OUT:Pointer to unused portion of zSql*/sqlite3*db,/*Database handle*/const char*zSql,/*SQL statement,UTF-8 encoded*/int nByte,/*Maximum length of zSql in bytes.*/sqlite3_stmt*ppStmt,/*OUT:Statement handle*/const char*pzTail/*OUT:Pointer to unused portion of zSql*/参数:db:数据指针zSql:sql语句,使用UTF-8编码nByte:如果nByte小于0,则函数取出zSql中从开始到第一个0终止符的内容;如果nByte不是负的,那么它就是这个函数能从zSql中读取的字节数的最大值。如果nBytes非负,zSql在第一次遇见’/000/或’u000’的时候终止pzTail:上面提到zSql在遇见终止符或者是达到设定的nByte之后结束,假如zSql还有剩余的内容,那么这些剩余的内容被存放到pZTail中,不包括终止符ppStmt:能够使用sqlite3_step()执行的编译好的准备语句的指针,如果错误发生,它被置为NULL,如假如输入的文本不包括sql语句。调用过程必须负责在编译好的sql语句完成使用后使用sqlite3_finalize()删除它。说明如果执行成功,则返回SQLITE_OK,否则返回一个错误码。推荐在现在任何的程序中都使用sqlite3_prepare_v2这个函数,sqlite3_prepare只是用于前向兼容备注准备语句(prepared statement)对象typedef struct sqlite3_stmt sqlite3_stmt;准备语句(prepared statement)对象一个代表一个简单SQL语句对象的实例,这个对象通常被称为“准备语句”或者“编译好的SQL语句”或者就直接称为“语句”。语句对象的生命周期经历这样的过程:l 使用sqlite3_prepare_v2或相关的函数创建这个对象l 使用sqlite3_bind_*()给宿主参数(host parameters)绑定值l 通过调用sqlite3_step一次或多次来执行这个sqll 使用sqlite3—reset()重置这个语句,然后回到第2步,这个过程做0次或多次l 使用sqlite3_finalize()销毁这个对象在sqlite中并没有定义sqlite3_stmt这个结构的具体内容,它只是一个抽象类型,在使用过程中一般以它的指针进行操作,而sqlite3_stmt类型的指针在实际上是一个指向Vdbe的结构体得指针宿主参数(host parameters)在传给sqlite3_prepare_v2()的sql的语句文本或者它的变量中,满足如下模板的文字将被替换成一个参数:l?l?NNN,NNN代表数字l:VVV,VVV代表字符l@VVVl$VVV在上面这些模板中,NNN代表一个数字,VVV代表一个字母数字标记符(例如:222表示名称为222的标记符),sql语句中的参数(变量)通过上面的几个模板来指定,如“select?from?“这个语句中指定了两个参数,sqlite语句中的第一个参数的索引值是1,这就知道这个语句中的两个参数的索引分别为1和2,使用”?的话会被自动给 予索引值,而使用”?NNN”则可以自己指定参数的索引值,它表示这个参数的索引值为NNN。VVV”表示一个名为”VVV”的参数,它也有一个索引 值,被自动指定。可以使用sqlite3_bind_*()来给这些参数绑定值3.sqlite3_setp()这个过程用于执行有前面sqlite3_prepare创建的准备语句。这个语句执行到结果的第一行可用的位置。继续前进到结果的第二行的话,只需再次调 用sqlite3_setp()。继续调用sqlite3_setp()知道这个语句完成,那些不返回结果的语句(如:INSERT,UPDATE,或 DELETE),sqlite3_step()只执行一次就返回函数定义int sqlite3_step(sqlite3_stmt*);返回值函数的返回值基于创建sqlite3_stmt参数所使用的函数,假如是使用老版本的接口sqlite3_prepare()和 sqlite3_prepare16(),返回值会 是 SQLITE_BUSY,SQLITE_DONE,SQLITE_ROW,SQLITE_ERROR 或 SQLITE_MISUSE,而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()则会同时返 回这些结果码和扩展结果码。对所有V3.6.23.1以及其前面的所有版本,需要在sqlite3_step()之后调用sqlite3_reset(),在后续的sqlite3_step之前。如果调用sqlite3_reset重置准备语句失败,将会导致sqlite3_step返回SQLITE_MISUSE,但是在V3.6.23.1以后,sqlite3_step()将会自动调用sqlite3_reset。int sqlite3_reset(sqlite3_stmt*pStmt);sqlite3_reset用于重置一个准备语句对象到它的初始状态,然后准备被重新执行。所有sql语句变量使用sqlite3_bind*绑定值,使 用sqlite3_clear_bindings重设这些绑定。Sqlite3_reset接口重置准备语句到它代码开始的时候。sqlite3_reset并不改变在准备语句上的任何绑定值,那么这里猜测,可能是语句在被执行的过程中发生了其他的改变,然后这个语句将它重置到绑定值的时候的那个状态。4.sqlite3_column()这个过程从执行sqlite3_step()执行一个准备语句得到的结果集的当前行中返回一个列。每次sqlite3_step得到一个结果集的列停下后,这个过程就可以被多次调用去查询这个行的各列的值。对列操作是有多个函数,均以sqlite3_column为前缀const void*sqlite3_column_blob(sqlite3_stmt*,int iCol);int sqlite3_column_bytes(sqlite3_stmt*,int iCol);int sqlite3_column_bytes16(sqlite3_stmt*,int iCol);double sqlite3_column_double(sqlite3_stmt*,int iCol);int sqlite3_column_int(sqlite3_stmt*,int iCol);sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*,int iCol);const unsigned char*sqlite3_column_text(sqlite3_stmt*,int iCol);const void*sqlite3_column_text16(sqlite3_stmt*,int iCol);int sqlite3_column_type(sqlite3_stmt*,int iCol);sqlite3_value*sqlite3_column_value(sqlite3_stmt*,int iCol);www.zgxue.com防采集请勿采集本网。

前言

本文给大家展示的代码实际上就是如何利用Sqlite3的参数化机制做数据插入,也可以update操作,就看你怎么玩了,这里只列出代码,然后说一些注意事项。

Sqlite默认保存数据是用UTF8格式,而现有程序开发工具都是默认GB2312的格式,所以你编程写的中文不转码直接写到库里后,用任何数据库工具看肯定都是乱码。但是读出来之后仍然是GB2312,所以显示正常。反之

下面的代码,有一个问题,插入后的东西一定是:

@Override 根据—_id筛选数据*/ public User Select(String id){ Cursor cursor=db.rawQuery(\"SELECT*FROM user WHERE_id=?and name=?这里可以添加筛选条件 new String[]{ id });if(cursor.

INSERT INTO "work" VALUES('铪','铪铪铪铪铪',NULL,NULL,NULL,NULL,'铪铪铪铪铪',NULL,NULL,110.0,1.0,108.9,NULL,NULL,'铪铪铪铪铪',NULL,NULL,NULL,'铪铪铪铪铪',NULL,NULL,NULL);

sqlite3 提供了各种语言的 API 绑定,C 语言的当然也有,具体参考 https://www.sqlite.org/capi3ref.html

看看有问题的代码:

sqlite3 的源码,好像是 sqlite3.h sqlite3_ext.h 以及 sqlite3.cc 可以将源码编译成库(静态库或者动态库),或者直接嵌入到工程中参与编译 数据库操作的一般流程是: sqlite3_open()/sqlite3_open_

sqlite3_stmt *stmt; CString sql = "insert into work values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; int rc = sqlite3_prepare_v2(db, sql.GetString(), -1, &stmt, NULL); if(rc != SQLITE_OK) { MessageBox("sqlite3_prepare_v2 Failed!"); return; } count = 0; p_wnd = PrevWnd; while(count++ < ID_TOTALCOUNT) { CString DbStr; p_wnd = CWnd::GetNextDlgTabItem(p_wnd, FALSE); if(p_wnd == NULL) { return; } p_wnd->GetWindowText(DbStr); do { if(!DbStr.GetLength()) { rc = sqlite3_bind_null(stmt, count); break; } //日期相关 if( count == ID_CHUDANRIQI || count == ID_CHUFARIQI || count == ID_HUANKUANRIQI || count == ID_HUOLIRIQI) { CDateTimeCtrl *TimeCtl = (CDateTimeCtrl *)p_wnd; CString time = DateTimeToString(*TimeCtl); rc = sqlite3_bind_text(stmt, count, time.GetString(), time.GetLength(), SQLITE_STATIC); break; } else { //金钱相关的处理real类型 if( count == ID_BAOXIANJINE || count == ID_YONGJINBILV || count == ID_JINGBAOFEI || count == ID_HUANKUANJINE || count == ID_LIRUNBILV || count == ID_LIRUNJINE) { double tMoney = 0.0; int rtn = sscanf_s(DbStr.GetString(), "%lf", &tMoney); ASSERT(rtn == 1); rc = sqlite3_bind_double(stmt, count, tMoney); } else { char *str = (char *)DbStr.GetString(); int c = strlen(str); int c1 = DbStr.GetLength(); rc = sqlite3_bind_text(stmt, count, DbStr.GetString(), -1/*DbStr.GetLength()*/, SQLITE_STATIC); } } }while(0); if(rc != SQLITE_OK) { CString ErrStr = sqlite3_errstr(rc); MessageBox(ErrStr); return; } } rc = sqlite3_step(stmt); if(rc != SQLITE_DONE) { if(rc == SQLITE_ERROR) { CString DbErr; DbErr.Format("Sql Insert failed, %s", sqlite3_errmsg(db)); MessageBox(DbErr); } else { MessageBox("sqlite3_step Failed!"); } } sqlite3_finalize(stmt);

Sqlite v三数据库任何列除整形主键列用于存储任何存储列值sql语句所值管嵌入sql文本或者作参数绑定预编译sql语句存储类型都未定面描述情况数据库引擎查询执行程数值(numeric)存储类型

为什么呢?

因为,sqlite3_bind_text绑定的text,需要在做:

rc = sqlite3_step(stmt);

的时候统一提交,而上面的代码使用的临时变量,rc = sqlite3_step(stmt);的时候,早就不存在了。因此乱码也是正常的。

修改如下:

sqlite3_stmt *stmt; CString sql = "insert into work values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; int rc = sqlite3_prepare_v2(db, sql.GetString(), -1, &stmt, NULL); if(rc != SQLITE_OK) { MessageBox("sqlite3_prepare_v2 Failed!"); return; } count = 0; p_wnd = PrevWnd; CString DbStr[ID_TOTALCOUNT + 1]; while(count++ < ID_TOTALCOUNT) { DbStr[count].Empty(); p_wnd = CWnd::GetNextDlgTabItem(p_wnd, FALSE); if(p_wnd == NULL) { return; } p_wnd->GetWindowText(DbStr[count]); do { if(!DbStr[count].GetLength()) { rc = sqlite3_bind_null(stmt, count); break; } //日期相关 if( count == ID_CHUDANRIQI || count == ID_CHUFARIQI || count == ID_HUANKUANRIQI || count == ID_HUOLIRIQI) { CDateTimeCtrl *TimeCtl = (CDateTimeCtrl *)p_wnd; CString time = DateTimeToString(*TimeCtl); DbStr[count] = time; rc = sqlite3_bind_text(stmt, count, time.GetString(), time.GetLength(), SQLITE_STATIC); } else { //金钱相关的处理real类型 if( count == ID_BAOXIANJINE || count == ID_YONGJINBILV || count == ID_JINGBAOFEI || count == ID_HUANKUANJINE || count == ID_LIRUNBILV || count == ID_LIRUNJINE) { double tMoney = 0.0; int rtn = sscanf_s(DbStr[count].GetString(), "%lf", &tMoney); ASSERT(rtn == 1); rc = sqlite3_bind_double(stmt, count, tMoney); } else { rc = sqlite3_bind_text(stmt, count, DbStr[count].GetString(), DbStr[count].GetLength(), SQLITE_STATIC); } } }while(0); if(rc != SQLITE_OK) { CString ErrStr = sqlite3_errstr(rc); MessageBox(ErrStr); return; } } rc = sqlite3_step(stmt); if(rc != SQLITE_DONE) { if(rc == SQLITE_ERROR) { CString DbErr; DbErr.Format("Sql Insert failed, %s", sqlite3_errmsg(db)); MessageBox(DbErr); } else { MessageBox("sqlite3_step Failed!"); } } sqlite3_finalize(stmt);

附上数据库创建的sql语法:

sqlite> .dump workPRAGMA foreign_keys=OFF;BEGIN TRANSACTION;CREATE TABLE work (baodanhao text unique primary key , chudanriqi text,qudao text,lianxiren text,xiaoshou text,beibaorenxingming text,chufariqi text,baoxianpinpai text,baoxianjihua text,baoxianjine real,yongjinbilv real,jingbaofei real,huankuanfangshi text,haikuanjine real,huankuanriqi text,shifouquane text,lirunbilv real,lirunjine real,huoliriqi text,fapiaojisong text,shifubaoxiangongsi text,beizhu text);

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对真格学网的支持。

[DCC Error]Unit1.pas(57):E2003 Undeclared identifier:'OpenDialog1'[DCC Error]Unit1.pas(57):E2066 Missing operator or semicolon[DCC Error]Unit1.pas(58):E2029 'THEN' expected but identifier 'Execute' found[DCC Fatal Error]Project1.dpr(5):F2063 Could not compile used unit 'Unit1.pas'答题不易,互相帮助,手机提问的朋友在客户端右上角评价点满意即可.如认可我的回答,请点击采纳为满意回答按钮内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • sqlite3中的日期时间函数使用小结
  • 为sqlite3提供一个ansi到utf8的互转函数
  • 初识sqlite3数据库
  • sqlite数据库管理系统-我所认识的数据库引擎
  • sqlite3 top的查询及limit语法介绍
  • sqlite 入门教程三 好多约束 constraints
  • sqlite教程(十三):c语言编程实例代码(1)
  • sqlite 常用函数 推荐
  • sqlite中重置自动编号列的方法
  • sqlite 入门教程一 基本控制台(终端)命令
  • sqlite教程(九):在线备份
  • sqlite 错误码整理
  • sqlite3查询也需要绑定吗
  • sqlite3 数据库 最大支持多少条数据
  • 如何调用sqlite3.dll
  • sqlite3 字段数据类型怎么看
  • linux中sqlite3 参数绑定怎么解决乱码
  • Listview怎么绑定SQLite数据库?
  • 如何在Linux下用C/C++语言操作数据库sqlite3
  • 如何在Linux下用C语言操作数据库sqlite3.pdf
  • sqlite 字段设置什么类型
  • 在linux c 下怎样向sqlite数据库表中插入满足下面条件的数据啊?
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全mssqlmysqlmariadboracledb2mssql2008mssql2005sqlitepostgresqlmongodbredisaccess数据库文摘数据库其它首页sqlitesqlite3中的日期时间函数使用小结为sqlite3提供一个ansi到utf8的互转函数初识sqlite3数据库sqlite数据库管理系统-我所认识的数据库引擎sqlite3 top的查询及limit语法介绍sqlite 入门教程三 好多约束 constraintssqlite教程(十三):c语言编程实例代码(1)sqlite 常用函数 推荐sqlite中重置自动编号列的方法sqlite 入门教程一 基本控制台(终端)命令sqlite教程(九):在线备份sqlite 错误码整理sqlite中文乱码问题原因分析及解sqlite3中的日期时间函数使用小结sqlite3 top的查询及limit语法介linux sqlite3 基本命令sqlite 错误码整理sqlite3中自增主键相关知识总结sqlite优化方法sqlite循环批量插入数据采用批处sqlite3 使用总结sqlite 常用函数 推荐一些很有用的sqlite命令总结sqlite教程(十二):锁和并发控制详解sqlite教程(二):c/c++接口简介sqlite 操作类代码sqlite 入门教程三 好多约束 constraints初识sqlite3数据库sqlite中的wal机制详细介绍sqlite 内存数据库学习手册sqlite中文乱码问题原因分析及解决sqlite 入门教程四 增删改查 有讲究
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved