上一篇:SQLiteC/C++接口详细介绍之sqlite3类(三)
下一篇:SQLiteC/C++接口详细介绍之sqlite3类(五)(暂未发表)
编写不易,有用的朋友点个赞或加粉一下万分感谢!300名内回关!
9、跟踪和分析功能相关的sqlite3_profile与sqlite3_trace(注意:这些例程官方已弃用不建议新工程建议用,而用sqlite3_trace_v2()替代)
void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
void *sqlite3_profile(sqlite3*, void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
这些函数注册可用于跟踪和分析SQL语句的执行。
由sqlite3_trace()注册的回调函数在sqlite3_step()运行SQL语句的各种时间。sqlite3_trace()回调是使用UTF-8渲染的SQL语句文本作为语句首先开始执行。可能会出现其他sqlite3_trace()回调输入每个触发的子程序。触发器的回调包含标识触发器的UTF-8SQL注释。
SQLITE_TRACE_SIZE_LIMIT编译时选项可用于限制sqlite3_trace()输出中绑定参数展开的长度。
调用sqlite3_profile()注册的回调函数当每个SQL语句完成时。配置文件回调包含原始声明文本和挂钟时间的估计值该声明运行了多长时间。配置文件回调时间以纳秒为单位,但当前的实现只能达到毫秒级分辨率,所以六个最不重要时间中的数字是没有意义的。SQLite的未来版本可能会在探查器回调上提供更高的分辨率。调用sqlite3_trace()或sqlite3_trace_v2()将取消配置文件回调。
sqlite3trace函数的基本使用方法如下: int sqlite3trace(sqlite3, void(xTrace)(void, const char), void* ); 其中,第一个参数为数据库句柄,第二个参数为一个回调函数(callback function),用于处理跟踪信息,第三个参数为一个上下文参数,可选。当SQL查询执行时,SQLite将会对查询中的每一步操作都调用该回调函数,并将相应的跟踪信息作为参数传递给它。
sqlite3_trace函数的回调函数需要接收两个参数:第一个参数为在SQLite中执行的SQL查询语句的文本,第二个参数为指向查询文本结尾的空指针。我们可以在该回调函数中将获取到的跟踪信息输出到标准错误流、文本文件或其他日志记录器中,以便进一步分析和调试。
sqlite3profile函数的基本使用方法如下: int sqlite3profile(sqlite3, void(xProfile)(void,const char,sqlite3_uint64), void* ); 其中,第一个参数为数据库句柄,第二个参数为回调函数(callback function),用于处理性能分析信息,第三个参数为一个上下文参数,可选。当SQL查询执行时,SQLite将会对查询中的每一步操作的各种信息都调用该回调函数,并将相应的性能分析信息作为参数传递给它。
sqlite3_profile函数的回调函数需要接收三个参数:第一个参数为查询的文本,第二个参数为指向查询文本结尾的空指针,第三个参数为表示该查询步骤执行所需时间的64位整数,单位是毫秒。我们可以在该回调函数中处理性能分析信息,比如将查询和执行时间保存到文件中或打印到终端上,以便进一步分析和优化程序的性能。
注意:sqlite3_trace、sqlite3profile函数可能会影响预期的性能,因为它会在执行过程中多次回调,所以在不需要跟踪SQL查询的时候,应该将其关闭。
10、sqlite3_blob_open功能:打开一个已存在于数据库中的BLOB数据(二进制大型对象)
int sqlite3_blob_open(
sqlite3*, /*数据库连接*/
const char *zDb, /*数据库名,如果直接传NULL,则表示打开默认数据库*/
const char *zTab, /*目标表名*/
const char *zCol, /*目标列名*/
sqlite3_int64 iRow,/*对应行的主键值*/
int flags, /*标记位*/
sqlite3_blob** pp /*BLOB句柄*/
);
其中,参数为数据库名,如果直接传NULL,则表示打开默认数据库;参数表示目标表名,表示目标BLOB列名;表示对应行的主键值;表示标记位,可以为、和等。用来保存指向打开的BLOB数据的句柄。
通过函数打开BLOB数据之后,我们就可以使用和函数来进行读取和写入操作。
注意:在打开BLOB数据时,数据库连接对象必须被正确的初始化并且没有激活的事务。当我们完成所有的读写操作后,需要使用函数调用sqlite3_blob_close()来关闭BLOB数据的句柄。
此接口打开位于BLOB的句柄在数据库zDb中的行iRow、列zColumn、表zTable中;换言之,将选择的相同BLOB:
SELECTzColumnFROMzDb.zTableWHERErowid=iRow;
参数zDb不是包含数据库的文件名,而是而是数据库的符号名称。对于附加的数据库,这是在ATTACH语句中AS关键字后面显示的名称。对于主数据库文件,数据库名称为“main”。对于TEMP表,数据库名称为“temp”。
如果flags参数不为零,则打开BLOB进行读取和写入访问权限。如果flags参数为零,则为只读访问权限。
成功后,将返回SQLITE_OK并存储新的BLOB句柄在*ppBlob中。否则,将返回错误代码,除非错误code为SQLITE_MISUSE,*ppBlob设置为NULL。这意味着,如果API没有被滥用,在它返回此函数后,在*ppBlob上调用sqlite3_blob_close()始终是安全的。
如果满足以下任一条件,则此函数将失败并显示SQLITE_ERROR:
数据库zDb不存在,
表zTable在数据库zDb中不存在,
TablezTable是一个WITHOUTROWID表,
列zColumn不存在,
表中不存在RowiRow,
行iRow的指定列包含的值不是TEXT或BLOB值,
列zColumn是索引、PRIMARYKEY或UNIQUE的一部分约束,并且正在打开blob进行读/写访问,
启用外键约束,列zColumn是子键定义的一部分,blob是正在打开以进行读/写访问。
除非它返回SQLITE_MISUSE,否则此函数设置可通过sqlite3_errcode()和sqlite3_errmsg()及相关函数访问的数据库连接错误代码和消息。
可以使用sqlite3_blob_read()接口读取sqlite3_blob_open()引用的BLOB,并使用sqlite3_blob_write()进行修改。BLOB句柄可以移动到使用sqlite3_blob_reopen()接口的同一表的不同行。但是,打开BLOB句柄后,无法更改BLOB句柄的列、表或数据库。
如果BLOB句柄指向的行由UPDATE、DELETE或ONCONFLICT修改副作用则BLOB句柄标记为“已过期”。如果更改了行的任何列,甚至是一列,则为真BLOB句柄打开的句柄除外。调用sqlite3_blob_read()和sqlite3_blob_write()过期的BLOB句柄失败,返回代码为SQLITE_ABORT。在BLOB过期之前写入BLOB的更改不会在BLOB过期时回滚。这些变化最终会如果事务继续完成,则提交。
使用sqlite3_blob_bytes()接口确定打开的Blob。Blob的大小可能不会因此而改变接口。使用UPDATESQL命令更改斑点。
sqlite3_bind_zeroblob()和sqlite3_result_zeroblob()接口内置的zeroblobSQL函数可用于创建一个要使用Incremental-blob接口读取或写入的零填充Blob。
注意:为了避免资源泄漏,每个打开的BLOB句柄最终都应通过调用sqlite3_blob_close()释放。
11、sqlite3_db_mutex函数获取绑定到给定数据库连接的互斥锁(mutex)。
SQLite使用互斥锁维护数据库内部的数据一致性和线程安全性,保证同一时刻只有一个线程能够访问某个特定的数据库连接。在多线程程序中使用SQLite进行数据访问时,我们需要首先使用函数获取对应的互斥锁,然后才能使用该数据库连接进行读写操作。
而函数就可以返回与某个数据库连接绑定的互斥锁对象的指针,从而方便我们获取到该数据库连接的互斥锁这个函数的使用方法如下:
sqlite3_mutex* sqlite3_db_mutex(sqlite3* db);
其中,参数表示要获取互斥锁的数据库连接对象。调用该函数会返回类型的互斥锁对象指针。
注意:使用函数获取到的互斥锁只能保护该数据连接对象本身,而不能保证整个数据库的线程安全性。要保证整个数据库的线程安全性,我们需要使用SQLite提供的全局互斥锁对象(全局互斥锁可以使用函数来分配)。
12、中断长时间运行的查询sqlite3_interrupt与sqlite3_is_interrupted函数
用于发送中断信号(例如SIGINT)给正在执行的SQL查询语句,以立即中止正在进行的操作。该函数可以在多线程或异步I/O等环境中使用,让我们能够更加有效地控制SQL查询的执行。
此函数会导致任何挂起的数据库操作中止,并且尽早返回。此例程通常为为响应用户操作(如按“取消”)而调用或Ctrl-C,用户希望停止长时间的查询操作马上。
从与当前正在运行数据库操作的线程。但它使用数据库连接调用此例程是不安全的在sqlite3_interrupt()返回之前已关闭或可能关闭。
如果SQL操作在以下时间几乎完成sqlite3_interrupt()被调用,那么它可能没有机会被中断,并可能继续完成。
中断的SQL操作将返回SQLITE_INTERRUPT。如果中断的SQL操作是INSERT、UPDATE或DELETE即在显式事务中,然后是整个事务将自动回滚。
sqlite3_interrupt(D)调用一直有效,直到所有当前都在运行数据库连接D上的SQL语句完成。任何新的SQL语句在sqlite3_interrupt()调用之后和运行语句计数达到零时会中断,就好像它们被打断了一样在sqlite3_interrupt()调用之前运行。新的SQL语句在运行语句计数达到零后启动的为不受sqlite3_interrupt()的影响。对sqlite3_interrupt(D)的调用,当没有运行时发生SQL语句是无操作,对SQL语句没有影响在sqlite3_interrupt()调用返回后启动。
sqlite3_is_interrupted(D)接口可用于确定是否或者当前对数据库连接D没有中断。如果中断当前有效,则返回1,否则返回0。
13.sqlite3_progress_handler函数:
设置一个进度回调函数,当SQL查询语句执行的进度符合某个特定的标准时,就会调用指定的回调函数。这个函数通常用来监测长时间运行的查询,以提供更新或取消查询的功能。用法如下:
void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
其中,第一个参数是数据库连接句柄,第二个参数是步长(一个非负整数),每次查询完成这个步数后会调用回调函数。第三个参数指定回调函数的指针,第四个参数是传递给回调函数的参数。
在运行查询时,SQLite会定期调用这个回调函数以检查查询的运行状态。如果“步数”被执行,则回调函数被调用。注意,此函数在大多数情况下尽最大努力会每处理完一个查询就调用一次回调函数,不过在低级别I/O操作时,可能存在队列区块大小等问题。
回调函数应该返回一个非零值,以表示希望取消查询或执行某些其他处理;返回零则表示要继续执行查询(不进行任何其他处理)。
注意:函数不是一个使查询更快完成的手段,而是一个监测工具,用于提供查询的更新或取消功能。对于长时间运行的查询,应该适当地使用这个函数,以避免程序因为长次运行而出现阻塞的情况。
参考文献:
1. C-language Interface Specification for SQLite官方说明文档