sqlite3中BLOB数据类型存储大对象运用示例

1:常用接口

个人比较喜欢sqlite,使用最方便,唯一的准备工作是下载250K的源;而且作者很热心,有问必答。

以下演示一下使用sqlite的步骤,先创建一个数据库,然后查询其中的内容。2个重要结构体和5个主要函数:

sqlite3 *pdb,数据库句柄,跟文件句柄FILE很类似

sqlite3_stmt *stmt,这个相当于ODBC的Command对象,用于保存编译好的SQL语句

sqlite3_open(),打开数据库

sqlite3_exec(),执行非查询的sql语句

sqlite3_prepare(),准备sql语句,执行select语句或者要使用parameter bind时,用这个函数(封装了sqlite3_exec).

Sqlite3_step(),在调用sqlite3_prepare后,使用这个函数在记录集中移动。

Sqlite3_close(),关闭数据库文件

还有一系列的函数,用于从记录集字段中获取数据,如

sqlite3_column_text(),取text类型的数据。

sqlite3_column_blob(),取blob类型的数据

sqlite3_column_int(),取int类型的数据

2:sqlite数据类型介绍

在进行数据库Sql操作之前,首先有个问题需要说明,就是Sqlite的数据类型,和其他的数据库不同,Sqlite支持的数据类型有他自己的特色,这个特色有时会被认为是一个潜在的缺点,但是这个问题并不在我们的讨论范围之内。
大多数的数据库在数据类型上都有严格的限制,在建立表的时候,每一列都必须制定一个数据类型,只有符合该数据类型的数据可以被保存在这一列当中。而在 Sqlite 2.X中,数据类型这个属性只属于数据本生,而不和数据被存在哪一列有关,也就是说数据的类型并不受数据列限制(有一个例外:INTEGER PRIMARY KEY,该列只能存整型数据)。
但是当Sqlite进入到3.0版本的时候,这个问题似乎又有了新的答案,Sqlite的开发者开始限制这种无类型的使用,在3.0版本当中,每一列开始 拥有自己的类型,并且在数据存入该列的时候,数据库会试图把数据的类型向该类型转换,然后以转换之后的类型存储。当然,如果转换被认为是不可行 的,Sqlite仍然会存储这个数据,就像他的前任版本一样。
举个例子,如果你企图向一个INTEGER类型的列中插入一个字符串,Sqlite会检查这个字符串是否有整型数据的特征,如果有而且可以被数据库所识别,那么该字符串会被转换成整型再保存,如果不行,则还是作为整型存储。

总的来说,所有存在Sqlite 3.0版本当中的数据都拥有以下之一的数据类型:
空(NULL):该值为空
整型(INTEGEER):有符号整数,按大小被存储成1,2,3,4,6或8字节。
实数(REAL):浮点数,以8字节指数形式存储。
文本(TEXT):字符串,以数据库编码方式存储(UTF-8,UTF-16BE 或者 UTF-16-LE)。
BLOB:BLOB数据不做任何转换,以输入形式存储。

ps: 在关系数据库中,CLOB和BLOB类型被用来存放大对象。BOLB表示二进制大对象,这种数据类型通过用来保存图片,图象,视频等。CLOB表示字符大对象,能够存放大量基于字符的数据。

对应的,对于数据列,同样有以下的数据类型:

TEXT
NUMERIC
INTEGER
REAL
NONE
数据列的属性的作用是确定对插入的数据的转换方向:

TEXT 将数据向文本进行转换,对应的数据类型为NULL,TEXT 或 BLOB
NUMERIC 将数据向数字进行转换,对应的数据类型可能为所有的五类数据,当试图存入文本 时将执行向整型或浮点类型的转换(视具体的数值而定),转换若不可行,则保留文本类型存储,NULL或BLOB不做变化
INTEGER 将数据向整型转换,类似于NUMERIC,不同的是没有浮点标志的浮点数将转换为整型保存
REAL 将数据向浮点数类型转换,类似于NUMERIC,不同的是整数将转换为浮点数保存
NULL 不做任何转换的数据列类型

实例代码如下,

附件工程可直接编译,例子使用了blob数据类型。

#include "sqlite3.h" //包含一个头文件就可以使用所以sqlite的接口了

#include "stdlib.h"

#include "stdio.h"

#include "string.h"

#pragma comment(lib,"sqlite.lib") //我把sqlite编译成了一个静态的lib文件。

void createdb();

void querydb();

int main()

{

createdb();

querydb();

return 0;

}

void createdb()

{

int ret;

sqlite3 *pdb = 0;

sqlite3_stmt *stmt = 0;

char *error = 0;

char *sql = "insert into table1 values('value11',:aaa)";

int &nbs; index;

static void *value = "asdfadsfasdfjasdfjaksdfaskjdfakdsfaksfja";

ret = sqlite3_open("db1.sdb",&pdb); //打开数据库,跟打开文本文件一样

if( ret != SQLITE_OK )

return;

ret = sqlite3_exec(pdb,"create table table1(col1 char(20),col2 BLOB)",&error );

if( ret != SQLITE_OK )

return;

ret = sqlite3_prepare(pdb,sql,strlen(sql),&stmt,&error);

if( ret != SQLITE_OK )

return;

index = sqlite3_bind_parameter_index(stmt,":aaa");

ret = sqlite3_bind_blob(stmt,index,value,strlen(value),SQLITE_STATIC);

if( ret != SQLITE_OK )

return;

ret = sqlite3_step(stmt);

if( ret != SQLITE_DONE )

return;

sqlite3_close(pdb);

}

void querydb()

{

int ret;

sqlite3 *pdb = 0;

sqlite3_stmt *pstmt = 0;

char *error = 0;

char *sql = "select * from table1";

int len;

int i;

char *name;

void *value;

ret = sqlite3_open("db1.sdb",&pdb);

if( ret != SQLITE_OK )

return;

ret = sqlite3_prepare(pdb,&pstmt,&error);

if( ret != SQLITE_OK )

return;

while( 1 )

{

ret = sqlite3_step(pstmt);

if( ret != SQLITE_ROW )

break;

name = sqlite3_column_text(pstmt,0);

value = sqlite3_column_blob(pstmt,1);

len = sqlite3_column_bytes(pstmt,1 );

}

}

实例二:SQLite中如何用api操作blob类型的字段

在实际的编程开发当中我们经常要处理一些大容量二进制数据的存储,如图片或者音乐等等。对于这些二进制数据(blob字段)我们不能像处理普通的文本那样 简单的插入或者查询,为此SQLite提供了一组函数来处理这种BLOB字段类型。下面的代码演示了如何使用这些API函数。

首先我们要建立一个数据库:

sqlite3_exec(db,"CREATE TABLE list (fliename varchar(128) UNIQUE,fzip blob);",&zErrMsg);

//由于mmmm.rar是一个二进制文件,所以要在使用insert语句时先用?号代替

sqlite3_prepare(db,"insert into list values ('mmmm.rar',?);",-1,&stat,0);

FILE *fp;

long filesize = 0;

char * ffile;

fp = fopen("mmmm.rar","rb");

if(fp != NULL)

{

//计算文件的大小

fseek(fp,SEEK_END);

filesize = ftell(fp);

fseek(fp,SEEK_SET);

//读取文件

ffile = new char[filesize+1];

size_t sz = fread(ffile,sizeof(char),filesize+1,fp);

fclose(fp);

}

//将文件数据绑定到insert语句中,替换“?”部分

sqlite3_bind_blob(stat,1,ffile,filesize,NULL);

//执行绑定之后的SQL语句

sqlite3_step(stat);

这时数据库当中已经有了一条包含BLOB字段的数据。接下来我们要读取这条数据:

//选取该条数据

sqlite3_prepare(db,"select * from list;",0);

sqlite3_step(stat);

//得到纪录中的BLOB字段

const void * test = sqlite3_column_blob(stat,1);

//得到字段中数据的长度

int size = sqlite3_column_bytes(stat,1);

//拷贝该字段

sprintf(buffer2,"%s",test);

此时可以将buffer2写入到文件当中,至此BLOB数据处理完毕。

实例三:sqlite 中用blob存储图片和取出图片

#include<iostream>
#include<string>
#include<sqlite3.h>

using namespace std;

int main()
{
sqlite3 *db;
sqlite3_stmt *stat;
char *zErrMsg = 0;

char buffer2[1024]="0";


sqlite3_open("./MetaInfo.db",&db);
int result;

if(result)
{
cout<<"Open the database sqlite.db failed"<<endl;
}

else
cout<<"Open the database sqlite.db sucessfully"<<endl;

sqlite3_exec(db,&zErrMsg);


sqlite3_prepare(db,"insert into list values ('./data/2.bmp',0);


FILE *fp;
long filesize = 0;
char * ffile;

fp = fopen("./data/2.bmp","rb");

if(fp != NULL)
{
fseek(fp,SEEK_END);
filesize = ftell(fp);
fseek(fp,SEEK_SET);

ffile = new char[filesize+1];
size_t sz = fread(ffile,fp);

fclose(fp);
}

sqlite3_bind_blob(stat,NULL);
sqlite3_step(stat);

sqlite3_prepare(db,0);
sqlite3_step(stat);

const void * test = sqlite3_column_blob(stat,1);
int size = sqlite3_column_bytes(stat,1);

sprintf(buffer2,test);

FILE *fp2;

fp2 = fopen("outfile.png","wb");

if(fp2 != NULL)
{
size_t ret = fwrite(test,size,fp2);
fclose(fp2);
}

delete(ffile);
sqlite3_finalize(stat); sqlite3_close(db); return 0; }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 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="