SQlite数据库的C编程接口六 返回值和错误码Result Codes and Error Codes ——《Using SQlite》读书笔记

SQlite数据库的C编程接口(六)返回值和错误码(Result Codes and Error Codes) by斜风细雨QQ:253786989 2012-02-07

标准码(StandardCodes

下面是标准的返回值和错误码定义:

#define SQLITE_OK           0   /* Successful result */
/* beginning-of-error-codes */
#define SQLITE_ERROR        1   /* SQL error or missing database */
#define SQLITE_INTERNAL     2   /* 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 sqlite3_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   /* Unknown opcode in sqlite3_file_control() */
#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   /* Database is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT  19   /* Abort due to constraint 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_FORMAT      24   /* Auxiliary database format error */
#define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB      26   /* File opened that is not a database file */
#define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite3_step() has finished executing */
/* end-of-error-codes */

其中有些常量只由具体的某个函数返回,比如SQLITE_RANGE只会由sqlite3_bind_xxx函数返回。还有一些常量,比如SQLITE_ERROR只能说明函数在执行过程中发生了错误,但无法知道错误发生的原因。

SQLITE_MISUSE代表API被误用。比如一条语句在sqlite3_step函数执行之后,没有被重置之前,再次给其绑定参数,这时bind函数就会返回SQLITE_MISUSE

扩展码(ExtendedCodes

标准错误码对于错误发生的原因,所提供的信息比较少。所以有时候,我们会使用扩展的错误码。扩展错误码是以标准错误码为基础,其低阶字节就是原本的标准错误码,然后在其高阶字节“或”上附加信息,描述错误发生的细节。

int sqlite3_extended_result_codes(sqlite3*,int onoff);

因为考虑到客户旧程序的兼容性问题,默认情况下,这些扩展的错误码是没有启用的。程序员可以通过sqlite3_extended_result_codes函数启用或者关闭扩展错误码。

下面是所有的扩展错误码(其中大部分用来描述SQLITE_IOERR):

#define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))
#define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))
#define SQLITE_IOERR_FSYNC             (SQLITE_IOERR | (4<<8))
#define SQLITE_IOERR_DIR_FSYNC         (SQLITE_IOERR | (5<<8))
#define SQLITE_IOERR_TRUNCATE          (SQLITE_IOERR | (6<<8))
#define SQLITE_IOERR_FSTAT             (SQLITE_IOERR | (7<<8))
#define SQLITE_IOERR_UNLOCK            (SQLITE_IOERR | (8<<8))
#define SQLITE_IOERR_RDLOCK            (SQLITE_IOERR | (9<<8))
#define SQLITE_IOERR_DELETE            (SQLITE_IOERR | (10<<8))
#define SQLITE_IOERR_BLOCKED           (SQLITE_IOERR | (11<<8))
#define SQLITE_IOERR_NOMEM             (SQLITE_IOERR | (12<<8))
#define SQLITE_IOERR_ACCESS            (SQLITE_IOERR | (13<<8))
#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
#define SQLITE_IOERR_LOCK              (SQLITE_IOERR | (15<<8))
#define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))

Error相关函数(ErrorFunctions

int sqlite3_extended_result_codes(sqlite3*,int onoff);

针对某个数据库连接,启用或关闭扩展错误码的使用。通过给sqlite3_extended_result_codes函数的第2个参数传递非零值来启用扩展错误码。该函数总是返回SQLITE_OK,没有什么途径可以获取扩展错误码当前是否启用或关闭。

int sqlite3_errcode(sqlite3 *db);

如果某个数据库函数操作没有返回SQLITE_OK,那么可以随后调用该函数获取错误码。默认情况下它返回标准错误码,如果当前数据库连接已经启用了扩展错误码,那么该函数也可能会返回一个扩展的错误码。

int sqlite3_extended_errcode(sqlite3 *db);

sqlite3_errcode函数类似,只不过该函数只会返回扩展的错误码。

const char *sqlite3_errmsg(sqlite3*);
const void *sqlite3_errmsg16(sqlite3*);

返回错误码字符串,使用UTF-8或者UTF-16编码。程序员应该在调用这两个函数,获取错误码信息之后立刻使用,或者做一个拷贝。因为下一个数据库操作就可能会导致返回的字符串指针失效。

SQlite错误处理不能够同时处理多个错误,比如某个API函数调用发生了错误,而程序员没有对该错误进行检查处理,那么下一次API函数调用就很可能返回SQLITE_MISUSE,表明程序试图使用一个无效的数据结构。所以程序员应该在每次API函数调用之后检查和处理任何可能发生的错误。

另外,如果多个线程分享同一个数据库连接,最好将核心的API调用和错误处理部分的代码封装在关键代码区(criticalsection)中。程序员可以使用sqlite3_db_mutex函数获取数据库连接的互斥锁指针(一个指向sqlite3_mutex对象的指针)。

V2版本的prepare函数(Preparev2

下表是原版本的prepare函数和v2版本的prepare函数的比较:

V2版本的prepare函数对于错误处理更简洁,还有上表中列出的关于schema的优点,所以推荐使用v2版本的prepare函数。

事务和错误(TransactionsandErrors

通常,SQlite操作处于自动提交模式。SQlite自动把每一个SQL命令封装进事务中。如果每条语句都被封装进它自己的事务中,那错误恢复就简单了。任何时候只要SQLite发现它自己处于错误状态,只要简单的回滚当前事务就可以了。这样就可以有效的取消当前SQL命令,并使数据库回到出错之前的状态。

然而,一旦BEGINTRANSACTION命令执行,SQlite就不在处于自动提交模式。一个事务被打开,将一直保持打开状态直到ENDTRANSACTION或者COMMITTRANSACTION命令执行。这就允许多条SQL命令封装进一个事务中,使一系列离散的命令要么全都执行,要么都不执行(原子操作),不过这也限制了SQLite的错误恢复。

当一个显示的(explicit)事务执行过程中遇到一个错误,SQLite试图取消刚刚执行的语句。不幸的是,这并不总是可能的。如果事情很糟,SQlite有时候只能回退整个当前事务,没有其他选择。

最有可能导致回滚的错误是SQLITE_FULL(数据库或磁盘空间已满),SQLITE_IOERR(磁盘IO错误或文件被锁定),SQLITE_BUSY(数据库锁定),SQLITE_NOMEM(内存不足),SQLITE_INTERRUPT(中断)。如果程序正在执行一个显示事务,并且收到这些错误之一,那就要准备好处理可能将发生的事务回滚。

int sqlite3_get_autocommit(sqlite3*);

通过该函数,可以获取当前的提交状态。如果返回非0值,则数据库处于自动提交(atutoconmit)模式。如果返回0,则数据库正处于一个显示事务之中(thedatabaseiscurrentlyinsideanexplicittransaction)。

如果SQlite数据库被强制做了一次完全事务回滚操作,则数据库将再次变为事务自动提交模式。如果数据库不在自动提交模式,则它肯定处于一个事务之中,表明并不需要回滚。

SQlite数据库的C编程接口(六)返回值和错误码(Result Codes and Error Codes) by斜风细雨QQ:253786989 2012-02-07

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


SQLite架构简单,又有Json计算能力,有时会承担Json文件/RESTful的计算功能,但SQLite不能直接解析Json文件/RESTful,需要用Java代码硬写,或借助第三方类库,最后再拼成insert语句插入数据表,代码非常繁琐,这里就不展示了。参考前面的代码可知,入库的过程比较麻烦,不能只用SQL,还要借助Java或命令行。SPL是现代的数据计算语言,属于简化的面向对象的语言风格,有对象的概念,可以用点号访问属性并进行多步骤计算,但没有继承重载这些内容,不算彻底的面向对象语言。...
使用Python操作内置数据库SQLite以及MySQL数据库。
破解微信数据库密码,用python导出微信聊天记录
(Unity)SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。本教程将告诉您如何使用 SQLite 编程,并让你迅速上手。.................................
安卓开发,利用SQLite实现登陆注册功能
相比大多数数据库而言,具有等优势,广泛应用于、等领域。
有时候,一个项目只有一个数据库,比如只有SQLite,或者MySQL数据库,那么我们只需要使用一个固定的数据库即可。但是一个项目如果写好了,有多个用户使用,但是多个用户使用不同的数据库,这个时候,我们就需要把软件设计成可以连接多个数据库的模式,用什么数据库,就配置什么数据库即可。4.Users实体类,这个实体类要和数据库一样的,形成一一对应的关系。11.Sqlite数据库,需要在代码里面创建数据库,建立表,再建立数据。8.我们开启MySQL数据库,然后进行调试,看程序的结果。2.安装SqlSugar。
基于Android的背单词软件,功能强大完整。
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统。说白了就是使用起来轻便简单,
Android的简单购物车案例
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库...
Qt设计较为美观好看的登录注册界面(包含SQLite数据库以及TCP通信的应用)
SQLite是用C语言开发的跨平台小型数据库,可嵌入其他开发语言,也可在单机执行。SPL是用Java开发的跨平台的数据计算语言,可嵌入Java,可在单机执行,可以数据计算服务的形式被远程调用。两者的代码都是解释执行的。...
新建库.openDATA_BASE;新建表createtableLIST_NAME(DATA);语法:NAME关键字...<用逗号分割>删除表droptableNAME;查看表.schema查看表信息新建数据insertintoLIST_NAMEvalues();语法:CLASS,PARAMETER...,CLASS是类别,PARAMETER是参数<用逗号分割新建的
importsqlite3classDemo01:def__init__(self):self.conn=sqlite3.connect("sql_demo_001.db")self.cursor1=self.conn.cursor()self.cursor1.execute("select*fromtable_001wherename=?andid=?",('ssss&#0
 在客户端配置文件<configuration>节点下,添加:<connectionStrings>      <add name="localdb" connectionString="Data Source=config/local.db;Version=3;UseUTF16Encoding=True;" providerName="System.Data.SQLite.SQLiteFactory"/&g
提到锁就不得不说到死锁的问题,而SQLite也可能出现死锁。下面举个例子:连接1:BEGIN(UNLOCKED)连接1:SELECT...(SHARED)连接1:INSERT...(RESERVED)连接2:BEGIN(UNLOCKED)连接2:SELECT...(SHARED)连接1:COMMIT(PENDING,尝试获取EXCLUSIVE锁,但还有SHARED锁未释放,返回SQLITE_BUSY)连接2:INSERT...
SQLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以集成。Python就内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。在使用SQLite前,我们先要搞清楚几个概念:表
设计思想————首先要确定有几个页面、和每个页面的大致布局由于是入门,我也是学习了不是很长的时间,所以项目比较low。。。。第一个页面,也就是打开APP的首页面:今天这个博客,先实现添加功能!:首先对主界面进行布局:其中activity_main.xml的代码为<?xmlversion="1.0"encoding="