sqlite数据库的C编程接口(六)返回值和错误码(Result Codes and Error Codes) by斜风细雨QQ:253786989 2012-02-07
标准码(StandardCodes)
下面是标准的返回值和错误码定义:
[cpp] view plain copy print ? #definesqlITE_OK0/*Successfulresult*/ /*beginning-of-error-codes*/ #definesqlITE_ERROR1/*sqlerrorormissingdatabase*/ #definesqlITE_INTERNAL2/*Internallogicerrorinsqlite*/ #definesqlITE_PERM3/*AccesspermissiondenIEd*/ #definesqlITE_ABORT4/*Callbackroutinerequestedanabort*/ #definesqlITE_BUSY5/*Thedatabasefileislocked*/ #definesqlITE_LOCKED6/*Atableinthedatabaseislocked*/ #definesqlITE_NOMEM7/*Amalloc()Failed*/ #definesqlITE_Readonly8/*AttempttowriteaReadonlydatabase*/ #definesqlITE_INTERRUPT9/*Operationterminatedbysqlite3_interrupt()*/ #definesqlITE_IOERR10/*SomekindofdiskI/Oerroroccurred*/ #definesqlITE_CORRUPT11/*Thedatabasediskimageismalformed*/ #definesqlITE_NOTFOUND12/*UnkNownopcodeinsqlite3_file_control()*/ #definesqlITE_FulL13/*InsertionFailedbecausedatabaseisfull*/ #definesqlITE_CANtopEN14/*Unabletoopenthedatabasefile*/ #definesqlITE_PROTOCol15/*Databaselockprotocolerror*/ #definesqlITE_EMPTY16/*Databaseisempty*/ #definesqlITE_SCHEMA17/*Thedatabaseschemachanged*/ #definesqlITE_TOOBIG18/*StringorBLOBexceedssizelimit*/ #definesqlITE_CONSTRAINT19/*Abortduetoconstraintviolation*/ #definesqlITE_MISMATCH20/*Datatypemismatch*/ #definesqlITE_MISUSE21/*libraryusedincorrectly*/ #definesqlITE_NolFS22/*UsesOSfeaturesnotsupportedonhost*/ #definesqlITE_AUTH23/*AuthorizationdenIEd*/ #definesqlITE_FORMAT24/*Auxiliarydatabaseformaterror*/ #definesqlITE_RANGE25/*2ndparametertosqlite3_bindoutofrange*/ #definesqlITE_NOTADB26/*fileopenedthatisnotadatabasefile*/ #definesqlITE_ROW100/*sqlite3_step()hasanotherrowready*/ #definesqlITE_DONE101/*sqlite3_step()hasfinishedexecuting*/ /*end-of-error-codes*/#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)
标准错误码对于错误发生的原因,所提供的信息比较少。所以有时候,我们会使用扩展的错误码。扩展错误码是以标准错误码为基础,其低阶字节就是原本的标准错误码,然后在其高阶字节“或”上附加信息,描述错误发生的细节。
[cpp] view plain copy print ? intsqlite3_extended_result_codes(sqlite3*,intonoff);int sqlite3_extended_result_codes(sqlite3*,int onoff);
因为考虑到客户旧程序的兼容性问题,默认情况下,这些扩展的错误码是没有启用的。程序员可以通过sqlite3_extended_result_codes函数启用或者关闭扩展错误码。
下面是所有的扩展错误码(其中大部分用来描述sqlITE_IOERR):
[cpp] view plain copy print ? #definesqlITE_IOERR_READ(sqlITE_IOERR|(1<<8)) #definesqlITE_IOERR_SHORT_READ(sqlITE_IOERR|(2<<8)) #definesqlITE_IOERR_WRITE(sqlITE_IOERR|(3<<8)) #definesqlITE_IOERR_FSYNC(sqlITE_IOERR|(4<<8)) #definesqlITE_IOERR_DIR_FSYNC(sqlITE_IOERR|(5<<8)) #definesqlITE_IOERR_TruncATE(sqlITE_IOERR|(6<<8)) #definesqlITE_IOERR_FSTAT(sqlITE_IOERR|(7<<8)) #definesqlITE_IOERR_UNLOCK(sqlITE_IOERR|(8<<8)) #definesqlITE_IOERR_RDLOCK(sqlITE_IOERR|(9<<8)) #definesqlITE_IOERR_DELETE(sqlITE_IOERR|(10<<8)) #definesqlITE_IOERR_BLOCKED(sqlITE_IOERR|(11<<8)) #definesqlITE_IOERR_NOMEM(sqlITE_IOERR|(12<<8)) #definesqlITE_IOERR_ACCESS(sqlITE_IOERR|(13<<8)) #definesqlITE_IOERR_CHECKRESERVEDLOCK(sqlITE_IOERR|(14<<8)) #definesqlITE_IOERR_LOCK(sqlITE_IOERR|(15<<8)) #definesqlITE_IOERR_CLOSE(sqlITE_IOERR|(16<<8)) #definesqlITE_IOERR_DIR_CLOSE(sqlITE_IOERR|(17<<8)) #definesqlITE_IOERR_SHMOPEN(sqlITE_IOERR|(18<<8)) #definesqlITE_IOERR_SHMSIZE(sqlITE_IOERR|(19<<8)) #definesqlITE_IOERR_SHmlock(sqlITE_IOERR|(20<<8)) #definesqlITE_IOERR_SHMMAP(sqlITE_IOERR|(21<<8)) #definesqlITE_IOERR_SEEK(sqlITE_IOERR|(22<<8)) #definesqlITE_LOCKED_SHAREDCACHE(sqlITE_LOCKED|(1<<8)) #definesqlITE_BUSY_RECOVERY(sqlITE_BUSY|(1<<8)) #definesqlITE_CANtopEN_NOTEMPDIR(sqlITE_CANtopEN|(1<<8)) #definesqlITE_CORRUPT_VTAB(sqlITE_CORRUPT|(1<<8)) #definesqlITE_Readonly_RECOVERY(sqlITE_Readonly|(1<<8)) #definesqlITE_Readonly_CANTLOCK(sqlITE_Readonly|(2<<8))#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)
[cpp] view plain copy print ? intsqlite3_extended_result_codes(sqlite3*,int onoff);针对某个数据库连接,启用或关闭扩展错误码的使用。通过给sqlite3_extended_result_codes函数的第2个参数传递非零值来启用扩展错误码。该函数总是返回sqlITE_OK,没有什么途径可以获取扩展错误码当前是否启用或关闭。
[cpp] view plain copy print ? intsqlite3_errcode(sqlite3*db);int sqlite3_errcode(sqlite3 *db);
如果某个数据库函数 *** 作没有返回sqlITE_OK,那么可以随后调用该函数获取错误码。默认情况下它返回标准错误码,如果当前数据库连接已经启用了扩展错误码,那么该函数也可能会返回一个扩展的错误码。
[cpp] view plain copy print ? intsqlite3_extended_errcode(sqlite3*db);int sqlite3_extended_errcode(sqlite3 *db);
与sqlite3_errcode函数类似,只不过该函数只会返回扩展的错误码。
[cpp] view plain copy print ? constchar*sqlite3_errmsg(sqlite3*); constvoID*sqlite3_errmsg16(sqlite3*);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(中断)。如果程序正在执行一个显示事务,并且收到这些错误之一,那就要准备好处理可能将发生的事务回滚。
[cpp] view plain copy print ? intsqlite3_get_autocommit(sqlite3*);int sqlite3_get_autocommit(sqlite3*);
通过该函数,可以获取当前的提交状态。如果返回非0值,则数据库处于自动提交(atutoconmit)模式。如果返回0,则数据库正处于一个显示事务之中(thedatabaseiscurrentlyinsIDeanexplicittransaction)。
如果sqlite数据库被强制做了一次完全事务回滚 *** 作,则数据库将再次变为事务自动提交模式。如果数据库不在自动提交模式,则它肯定处于一个事务之中,表明并不需要回滚。
sqlite数据库的C编程接口(六)返回值和错误码(Result Codes and Error Codes) by斜风细雨QQ:253786989 2012-02-07
总结以上是内存溢出为你收集整理的SQlite数据库的C编程接口(六) 返回值和错误码(Result Codes and Error Codes) ——《Using SQlite》读书笔记全部内容,希望文章能够帮你解决SQlite数据库的C编程接口(六) 返回值和错误码(Result Codes and Error Codes) ——《Using SQlite》读书笔记所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)