- 浏览: 151571 次
- 性别:
- 来自: 北京
文章分类
最新评论
SQlite数据库的C编程接口(六) 返回值和错误码(Result Codes and Error Codes) ——《Using SQlite》读书笔记
SQlite数据库的C编程接口(六)返回值和错误码(Result Codes and Error Codes) by斜风细雨QQ:253786989 2012-02-07
标准码(StandardCodes)
下面是标准的返回值和错误码定义:
- #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)
标准错误码对于错误发生的原因,所提供的信息比较少。所以有时候,我们会使用扩展的错误码。扩展错误码是以标准错误码为基础,其低阶字节就是原本的标准错误码,然后在其高阶字节“或”上附加信息,描述错误发生的细节。
- intsqlite3_extended_result_codes(sqlite3*,intonoff);
int sqlite3_extended_result_codes(sqlite3*, int onoff);
因为考虑到客户旧程序的兼容性问题,默认情况下,这些扩展的错误码是没有启用的。程序员可以通过sqlite3_extended_result_codes函数启用或者关闭扩展错误码。
下面是所有的扩展错误码(其中大部分用来描述SQLITE_IOERR):
- #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)
- intsqlite3_extended_result_codes(sqlite3*,intonoff);
int sqlite3_extended_result_codes(sqlite3*, int onoff);
针对某个数据库连接,启用或关闭扩展错误码的使用。通过给sqlite3_extended_result_codes函数的第2个参数传递非零值来启用扩展错误码。该函数总是返回SQLITE_OK,没有什么途径可以获取扩展错误码当前是否启用或关闭。
- intsqlite3_errcode(sqlite3*db);
int sqlite3_errcode(sqlite3 *db);
如果某个数据库函数操作没有返回SQLITE_OK,那么可以随后调用该函数获取错误码。默认情况下它返回标准错误码,如果当前数据库连接已经启用了扩展错误码,那么该函数也可能会返回一个扩展的错误码。
- intsqlite3_extended_errcode(sqlite3*db);
int sqlite3_extended_errcode(sqlite3 *db);
与sqlite3_errcode函数类似,只不过该函数只会返回扩展的错误码。
- 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(中断)。如果程序正在执行一个显示事务,并且收到这些错误之一,那就要准备好处理可能将发生的事务回滚。
- 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) by斜风细雨QQ:253786989 2012-02-07
标准码(StandardCodes)
下面是标准的返回值和错误码定义:
- #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)
标准错误码对于错误发生的原因,所提供的信息比较少。所以有时候,我们会使用扩展的错误码。扩展错误码是以标准错误码为基础,其低阶字节就是原本的标准错误码,然后在其高阶字节“或”上附加信息,描述错误发生的细节。
- intsqlite3_extended_result_codes(sqlite3*,intonoff);
int sqlite3_extended_result_codes(sqlite3*, int onoff);
因为考虑到客户旧程序的兼容性问题,默认情况下,这些扩展的错误码是没有启用的。程序员可以通过sqlite3_extended_result_codes函数启用或者关闭扩展错误码。
下面是所有的扩展错误码(其中大部分用来描述SQLITE_IOERR):
- #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)
- intsqlite3_extended_result_codes(sqlite3*,intonoff);
int sqlite3_extended_result_codes(sqlite3*, int onoff);
针对某个数据库连接,启用或关闭扩展错误码的使用。通过给sqlite3_extended_result_codes函数的第2个参数传递非零值来启用扩展错误码。该函数总是返回SQLITE_OK,没有什么途径可以获取扩展错误码当前是否启用或关闭。
- intsqlite3_errcode(sqlite3*db);
int sqlite3_errcode(sqlite3 *db);
如果某个数据库函数操作没有返回SQLITE_OK,那么可以随后调用该函数获取错误码。默认情况下它返回标准错误码,如果当前数据库连接已经启用了扩展错误码,那么该函数也可能会返回一个扩展的错误码。
- intsqlite3_extended_errcode(sqlite3*db);
int sqlite3_extended_errcode(sqlite3 *db);
与sqlite3_errcode函数类似,只不过该函数只会返回扩展的错误码。
- 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(中断)。如果程序正在执行一个显示事务,并且收到这些错误之一,那就要准备好处理可能将发生的事务回滚。
- 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
相关推荐
内容概要:这是一个通过显式调用(dlopen)方式,使用SQLite库API函数C语言编程的demo示例。里面包含了SQLite数据库文件的创建、数据库表创建、插入、修改、删除、查询等功能操作。该资源包中的程序有在Ubuntu环境下...
验证android sqlite数据库insert 和delete 方法返回值的具体规律 insert 插入一行,如果当前最大id是4,insert新的一条记录id是5 ,如果把5删除, 在insert一条新的记录id还是5,如果删除的是id为4的记录, 再新增一...
2. **SQL接口层(应用编程层)**:这一层提供了数据库访问的高级接口,其中QSqlDatabase用于管理数据库连接,QSqlQuery用于执行SQL查询,QSqlError用于处理错误,QSqlField定义字段属性,QSqlTableModel和QSqlRecord...
标题“基于Qt4的SQLite数据库应用编程”揭示了文档将要介绍的知识点,即如何在Qt4框架下进行SQLite数据库的应用编程。从描述中我们知道,Qt是一个由挪威TrollTech公司开发的C++图形用户界面应用程序框架,支持跨平台...
SQLite数据库是一种轻量级、自包含的SQL数据库引擎,常被用在嵌入式系统和移动应用中。在处理敏感数据时,为了保护信息安全,对SQLite数据库进行加密是必要的步骤。本文将详细介绍如何使用.NET环境下的SQLite加密...
Sqlite数据库加密、解密工具,主要是用于进行给Sqlite数据库进行加密,修改密码的工具
这是一个使用C#开发的Sqlite数据库创建、操作的源码工程,关于Sqlite的所有操作已经单独创建了专门的跨平台【.NETCore3.1】类库包含相应的帮助类,可以直接生成后拿到任何项目中直接使用,高效简单,省去了从头开发...
Delphi版SQLite数据库工具是一款专为开发者设计的实用软件,主要用于在Delphi编程环境中与SQLite数据库进行交互。SQLite是一款轻量级、自包含的数据库引擎,广泛应用于嵌入式系统和移动应用,因其高效性和无需服务器...
Android SQLite 数据库操作报告 一、实验目的 Android 实验报告的主要目的是熟悉 Android 平台的文件操作、掌握 Android SQLite 数据库的设计和应用、熟悉 XML 和 JSON 文件的读取。通过本实验,用户可以掌握 ...
在VB6.0中操作SQLite数据库,是一种将轻量级、高性能的SQLite数据库与传统的Visual Basic编程环境相结合的方法。SQLite是一种自包含、无服务器、零配置、事务性的SQL数据库引擎,广泛应用于移动设备、嵌入式系统以及...
在Android系统中,SQLite是一个非常重要的组成部分,它是一个轻量级的、开源的、关系型数据库,被广泛用于存储和管理应用程序中的数据。这个压缩包文件"Android源码——数据库SQLite.zip"可能包含了关于Android中...
SQLite具有高度移植性,支持多种操作系统和编程语言,如Windows、Linux、Mac OS、Java、C++、Python等。它的设计目标是提供可靠的数据存储,同时保持简单易用和高效。 在描述中提到的“最好用的SQLite数据库打开...
1. **Web SQL Database**(不推荐):这是W3C曾经提出的一个标准,允许在Web应用中使用SQLite数据库。开发者可以通过SQL语法直接操作数据库。但请注意,这个标准已被废弃,不再推荐使用。 2. **IndexedDB**:这是一...
附件:SQLite3.dll 功能: 1.用纯脚本创建一个带密码的SQLite3数据库(默认文件名db.db,密码123) 2.用纯脚本创建一个表,并打开,可在Dbgrid中修改 3.修改SQLite3数据库的密码 备注:在不替换SQLite3.dll的前提下,本...
易语言是一种专为中国人设计的编程语言,它以简体中文作为编程语法,降低了编程的门槛,使得更多非...了解如何使用sqlite3.dll和相关接口,以及如何处理带密码的数据库,将大大提升你在易语言中的数据库编程能力。
"实验十 使用SQLite数据库存储数据"是一个旨在帮助开发者掌握如何在Android应用中集成和操作SQLite数据库的实践练习。 SQLite数据库在Android中的使用主要包括以下几个关键知识点: 1. **SQLiteOpenHelper**: 这是...
SQLite数据库逆向分析是指对SQLite数据库的逆向分析,以获取数据库的结构、数据和实现机理。本节课将从基本的Main函数开始,逐步深入到数据库的逆向分析。 2. Main函数分析 Main函数是程序的入口点,负责初始化...
SQLite3 C 语言接口是 SQLite3 数据库管理系统提供的一种编程接口,允许 C 语言程序员使用 SQLite3 数据库。该接口提供了一系列函数和数据结构,用于创建、操作和管理 SQLite3 数据库。 快速入门 SQLite3 C 语言...
SQlite数据库工具 供比较两个SQLite数据库所用。
全国省市区sqlite数据库是一种高效、轻量级的方式来存储和管理中国的行政区域划分数据。SQLite是一个开源的嵌入式关系数据库,它不需要单独的服务器进程,可以直接在应用程序中使用,非常适合处理小到中型规模的数据...