我正在使用SQLite的C接口,需要列出存储在TEXT列中的字符串的大小,即某些数据库使用
SELECT DATALENGTH(body) FROM table;但是,SQLite没有DATALENGTH函数。由于所讨论的文本相当大,我希望避免从磁盘加载实际的body列。由于TEXT是utf8,所以LENGTH(body)不返回所需的结果(它确实返回字符计数,而我需要知道存储大小)。将列转换为BLOB不是一个选项,因为数据库是由第三方程序创建的。
Q:,除了编写自定义SQL函数之外,还有什么方法可以直接从数据库获取这些信息吗?SQLite 文件格式确实存储了TEXT字段的长度,所以如果没有公开这些信息,我会感到很惊讶。
相关:
发布于 2020-04-07 14:49:32
转换为blob,以从length()获取大小(以字节为单位)
SELECT length(cast(body AS BLOB)) FROM table;发布于 2020-04-07 15:32:17
或者,对于@Shawn的回答,实现自定义SQL函数实际上相当简单:
/* Implement the DATALENGTH() SQL function. Code adapted from the SQLite source
* for the LENGTH() function.
*/
static void db_sqlite_datalength(sqlite3_context *context, int argc,
sqlite3_value **argv)
{
(void) argc;
switch(sqlite3_value_type(argv[0])) {
case SQLITE_BLOB:
case SQLITE_INTEGER:
case SQLITE_FLOAT:
case SQLITE_TEXT:
sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
break;
default:
sqlite3_result_null(context);
break;
}
}
static int db_register_custom_functions(sqlite3 *db)
{
return sqlite3_create_function(db, "datalength", 1,
SQLITE_UTF8 | SQLITE_DETERMINISTIC, NULL,
&db_sqlite_datalength, NULL, NULL);
}由于内置的length函数是以完全相同的方式实现的,所以性能应该是可以的。我浏览了一下sqlite3源代码,但是很难判断何时会发生磁盘访问。据推测,sqlite3 mmap的一切都是如此,对于性能来说,重要的是长TEXT字段的可能溢出页面不会被不必要地访问。
https://stackoverflow.com/questions/61081261
复制相似问题