sqlite3 函数有没有专门的插入函数

在SQLite中,INSERT INTO语句用于将新的数据行添加/插入到表中。 创建表后,该命令用于将数据插入到表中。
INSERT INTO语句有两种类型的基本语法:
INSERT INTO TABLE_NAME [(column1, column2, column3,...columnN)]
VALUES (value1, value2, value3,...valueN);
这里,column1,column2,column3,... columnN是指定要插入数据的表中的列的名称。
如果要向表中的所有列添加值,则不需要在SQlite查询中指定列名称。 但是,应该确保值的顺序与表中列的顺序相同。
那么,语法如下所示:
INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);
看下面一个例子,用来演示如何向SQLite数据库中执行INSERT查询语句。前面的文章中,已经创建了一个名为“student”的表。 现在向student表中插入一些数据记录。
注意:如还没有创建表,那么可以先参考:
使用第一种方法插入值:
INSERT INTO student (ID,NAME,AGE,ADDRESS,FEES)
VALUES (1, 'Maxsu', 27, 'Shengzhen', 20000.00);
INSERT INTO student (ID,NAME,AGE,ADDRESS,FEES)
VALUES (2, 'Minsu', 25, 'Beijing', 15000.00 );
INSERT INTO student (ID,NAME,AGE,ADDRESS,FEES)
VALUES (3, 'Avgsu', 23, 'Shanghai', 2000.00 );
INSERT INTO student (ID,NAME,AGE,ADDRESS,FEES)
VALUES (4, 'Linsu', 25, 'Guangzhou', 65000.00 );
INSERT INTO student (ID,NAME,AGE,ADDRESS,FEES)
VALUES (5, 'Sqlsu', 26, 'Haikou', 25000.00 );
执行上面代码,结果如下 -
使用第二种方法:
也可以通过第二种方法将数据插入到表中。
INSERT INTO student VALUES (6, 'Javasu', 21, 'Shengzhen', 18000.00 );
可以使用SELECT语句查看student表中的数据:
SELECT * FROM
为了方便后面学习使用,这里也准备了一些 department表的数据 -
INSERT INTO department (ID,DEPT,EMP_ID)
VALUES (1,'财务部', 1);
INSERT INTO department (ID,DEPT,EMP_ID)
VALUES (2,'技术部', 2);
INSERT INTO department (ID,DEPT,EMP_ID)
VALUES (3,'技术部', 3);
INSERT INTO department (ID,DEPT,EMP_ID)
VALUES (4,'市场部', 4);
INSERT INTO department (ID,DEPT,EMP_ID)
VALUES (5,'市场部', 5);
为了方便后面学习使用,这里也准备了一些 class表的数据 -
INSERT INTO class (id,class_name,student_id)
VALUES (1,'网络工程-001班', 1);
INSERT INTO class (id,class_name,student_id) VALUES (2,'网络工程-002班', 2);
INSERT INTO class (id,class_name,student_id)
VALUES (3,'网络工程-003班', 3);
INSERT INTO class (id,class_name,student_id)
VALUES (4,'网络工程-004班', 4);
本站所有代码下载:请扫描本页面底部(右侧)二维码并关注微信公众号,回复:"代码下载" 获取。
上一篇:下一篇:5647人阅读
SQLite 内置函数比较有限,有时通过添加自定义函数(User-Defined Fuctions)的方式可以实现一些通过普通 SQL 操作无法实现或者实现很麻烦的功能;也可以替换 SQLite 原有的内置函数,使其符合我们的要求。本文侧重说明在 Android 环境下的做法。
现在假设我们现在要在 Android 系统的视频播放器增加一个按照文件扩展名排序的功能,如果不是用自定义函数,就需要先从多媒体数据库中查询出来视频的路径,然后取出视频文件的扩展名并进行排序,因为查询得到的 Cursor 对象不可写,所以需要生成一个 MatrixCursor,把排序后的数据写入,最后返回这个 MatrixCursor。伪代码表示如下:
1 public Cursor getSortedByFileExtensionCursor() {
Cursor rawCursor = queryVideoFileNameFromDb(); // 从数据库查询出 id 和路径
HashMap&int,String& idAndExtensionMap = getVideoFileExtension(rawCursor); // 获取 id 和扩展名的 HashMap
Cursor result = sortAndCreateNewMatrixCursor(idAndExtensionMap); // 对扩展名进行排序,生成 MatrixCursor 作为结果
而如果我们能够向 SQLite 注册一个自定义函数,很多类似问题就要简单不少。
1. 通过 C 语言接口添加自定义函数
如果使用的是 Android 提供的 sqlite 程序,需要修改 Android 源码目录下的 external/sqlite/android/sqlite3_android.cpp 文件。注册一个自定义函数,函数名称是 get_file_ext,在 SQL 语句中的函数名称是 &_GET_FILE_EXT&,简要代码如下:
1 extern &C& int register_android_functions(sqlite3 * handle, int utf16Storage)
// 注册自定义函数
err = sqlite3_create_function(handle, &_GET_FILE_EXT&, 1, SQLITE_UTF8, NULL, get_file_ext, NULL, NULL);
if (err != SQLITE_OK) {
14 // 返回文件扩展名函数的具体实现
15 static void get_file_ext(sqlite3_context * context, int argc, sqlite3_value ** argv)
然后编译 external/sqlite,把编译出来的 libsqlite.so 替换手机 /system/lib/ 下面的库。使用该自定义函数也很简单:
1 public Cursor getSortedByFileExtensionCursor() {
// 在 sort by 那里使用我们的 SQLite 自定义函数
Cursor result = query(&SELECT * FROM video SORT BY _GET_FILE_EXT(_data)&);
Note:如果不是在 Android 环境下,或者无法修改 Android 相关代码,则需要自行通过 c 语言的接口操作数据库,然后同样使用 sqlite3_create_function 这个函数注册自定义函数。如果使用的是 C#/Python/PHP 等语言,这些语言都有相应的 SQLite wrapper,可以类似的操作数据库并注册自定义函数。
2. 通过 Java 语言接口添加自定义函数
Android SQLiteDatabase 类里面有一个添加自定义函数的隐藏接口(@hide),在 Android 源码中编译的话可以使用该接口,使用方法大致如下:
1 public class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
public void onOpen(SQLiteDatabase db) {
db.addCustomFunction(&_GET_FILE_EXT&, 1, mGetFileExtension);
private final SQLiteDatabase.CustomFunction mGetFileExtension =
new SQLiteDatabase.CustomFunction() {
public void callback(String[] args) {
String file = args[0];
int index = file.lastIndexOf(&.&);
if (index != -1 && file.length() & index + 1) {
return file.substring(index);
return null;
然后对这个数据库进行查询操作时,就可以使用我们添加的 _GET_FILE_EXT 函数了。Android 源码目录下的 pacakges/providers/MediaProvider 这个程序就使用了此接口,可以参考。
Note:对外发布的程序最好不要依赖隐藏的 Java 接口,兼容性难以保证。
扩展阅读:
:创建自定义函数的解释。
:使用 c 语言接口打开 SQLite 数据库的简单示例代码。
转载请注明出处:
本文外部镜像:/2013/06/how-to-add-user-defined-functions-for-sqlite.html&script type=&text/javascript&&&!--
google_ad_client = &ca-pub-8447&;
/* cnblogs 首页横幅 */
google_ad_slot = &&;
google_ad_width = 728;
google_ad_height = 90;
//--&&/script&&script type=&text/javascript& src=&/pagead/show_ads.js&&&/script&
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:9256550次
积分:95870
积分:95870
排名:第10名
原创:361篇
转载:4760篇
译文:17篇
评论:1777条
文章:21篇
阅读:49591
文章:15篇
阅读:37788
文章:22篇
阅读:210199
(4)(8)(28)(21)(47)(1)(1)(8)(170)(814)(1012)(1351)(969)(262)(207)(2)(3)(2)(61)(19)(2)(28)(22)(37)(1)(3)(4)(6)(9)(10)(26)sqlite3-------函数使用方法
此句能极大的提高效率
sqlite3_exec(db, "BEGIN;", 0, 0, &zErrMsg);
&&sqlite3_exec(db, "INSERT INTO
ReelShootCameraXYOffsetToYufei VALUES(0, 0, 0);", NULL, NULL,
&zErrMsg);
&&//在"BEGIN;"与"COMMIT;"之间可多条一起执行,提高效率
&&sqlite3_exec(db, "COMMIT;", 0,
0, &zErrMsg);
这篇文中主要记录sqlite3中,常用的函数的用法。
http://www.sqlite.org/cintro.html
所有的函数在这里都可以看到。
打开一个数据库
int sqlite3_open(
const char *filename,
sqlite3 **ppDb
int sqlite3_open16(
const void *filename,
sqlite3 **ppDb
int sqlite3_open_v2(
const char *filename,
sqlite3 **ppDb,
int flags,
const char *zVfs
const char *filename :指数据库名称。
然后传递一个**ppDb,而返回的连接句柄保存在*ppDb,所以我们声明一个sqlite3 *ppDb指针,传递进去&ppDb
若用sqlite3_open_v2,那么多了两个参数,其中flags的解释在http://www.sqlite.org/c3ref/c_open_autoproxy.html
The database is opened in read-only mode. If the database does
not already exist, an error is returned.
The database is opened for reading and writing if possible, or
reading only if the file is write protected by the operating
system. In either case the database must already exist, otherwise
an error is returned.
The database is opened for reading and writing, and is creates
it if it does not already exist. This is the behavior that is
always used for sqlite3_open() and sqlite3_open16().
第四个参数通常是null,选择默认的。
通常的做法是:
char * errmsg = NULL;
result = sqlite3_open("/ebframe/data/ebframe.db", &db );
if( result != SQLITE_OK )
fprintf(stderr, "Can't open database: %s", sqlite3_errmsg(db));
sqlite3_close(db);
return -1;
千万不要忘记在最后sqlite3_close(db);
sqlite3_prepare()
int sqlite3_prepare(
sqlite3 *db,
const char *zSql,
int nByte,
sqlite3_stmt **ppStmt,
const char **pzTail
int sqlite3_prepare_v2(
sqlite3 *db,
const char *zSql,
int nByte,
sqlite3_stmt **ppStmt,
const char **pzTail
官方文档推荐用sqlite3_prepare_v2(),因为这个函数有很多的好处。细节看http://www.sqlite.org/c3ref/prepare.html
sqlite3 *db,
这个就不解释了
const char *zSql
这个是要编译的zSQL语句,实际是个字符串
select * from table;
若nByte&0,那么zSQL将读到第一个'/0',若nByte&0,那么他就是读取nByte的数量,或者在'/0'结束
sqlite3_stmt **ppStmt ;声明的时候,声明sqlite3_stmt *ppStmt ,传递&ppStmt ,*ppStmt 指向编译好的zSql语句,这个语句将要被
执行,发生错误时ppStmt 被置为NULL。
成功执行函数返回:
,错误发生返回error,每个error定义在http://www.sqlite.org/c3ref/c_abort.html
sqlite3_stmt *ppStmt ;
sqlite3_prepare_v2(db,"insert into table(name,age,salary)values('stone','32','3455');",-1,&ppStmt,0);
sqlite3_finalize(stmt); 最后一步析构掉。
int sqlite3_step(sqlite3_stmt*)
这个函数执行sqlite3_prepare_v2()函数编译出来的结果,它每次执行只能出来一行的结果,若是还有多余的结果,那么还需要继续调用,直到语句执行完。
每执行一次,该函数将返回以下的返回值
&:数据库忙,现在不能使用。
&:此条语句执行完毕,若想在执行这个语句,那么必须使用&将虚拟机初始化到初始阶段,这样的目的是清&&&&&&&&&&&&&&&&&&&&
除已经绑定的参数。
&:如果正在执行一条语句,返回值将是这个,这时将输出一行执行结果,可供调用者调用,我们需要继续调用sqlite3_step来产生下一行的输出,使用&函数能获取到该行
&:运行时错误,这时不能再继续调用sqlite3_step()函数了。
其实没有这个函数,他只是个总称,它是一系列的函数
具体含义看http://www.sqlite.org/c3ref/column_blob.html
每个函数都返回sqlite3_step()输出的一行的其中一列的值,这样我们就需要调用多次获取每行的值
r = sqlite3_step(stmt);&
& const unsigned char *
& while( r == SQLITE_ROW
& & id = sqlite3_column_int(
stmt, 0 );&
& & name = sqlite3_column_text(
stmt,1 );&
& & number = sqlite3_column_int(
stmt, 2 );&
& & printf("ID:
%d& Name: %s& Age: %d
/n",id,name,number);&
sqlite3_step(stmt);&
int sqlite3_finalize(sqlite3_stmt *pStmt);他析构掉了由
生成的语句,以防止内存泄露。没执行完一条编译后的语句,都要
这么的析构下。
关闭和打开是对应的,千万别忘记。
sqlite3_bind
和sqlite3_column一样,他也是一系列的函数,我们必须选择的用,它是用来给sqlite3_stmt
*pStmt语句增加值的,对于不同类型的参数要选用不同的函数。
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
int sqlite3_bind_double(sqlite3_stmt*, int, double);
int sqlite3_bind_int(sqlite3_stmt*, int, int);
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
具体的每个用法查询http://www.sqlite.org/c3ref/bind_blob.html
下面的列子中包含了他的用法
& & & & sqlite3_prepare(db,
& & & & & & & & "INSERT INTO players (name,num) VALUES(?,?);",
& & & & & & & & -1,&stmt,&zTail);
& & & & char str[] = "Kevin";
& & & & int n = 23;
& & & & sqlite3_bind_text(stmt,1,str,-1,SQLITE_STATIC); //绑定数据
& & & & sqlite3_bind_int(stmt,2,n);
& & & & r = sqlite3_step(stmt);
& & & & if( r!=SQLITE_DONE){
& & & & & & & & printf("%s",sqlite3_errmsg(db));
& & & & sqlite3_reset(stmt);
//重新复位下stmt语句
& & & & //插入第二个数据
& & & & char str2[] = "Jack";
& & & & int n2 = 16;
& & & & sqlite3_bind_text(stmt,1,str2,-1,SQLITE_STATIC);
& & & & sqlite3_bind_int(stmt,2,n2);
& & & & r = sqltie3_step(stmt);
& & & & if( r!=SQLITE_DONE){
& & & & & & & & printf("%s",sqlite3_errmsg(db));
& & & & sqltie3_finalize(stmt);
int sqlite3_reset(sqlite3_stmt
复位有sqlite3_bind_text绑定的语句,这样可以重新再用pstmt语句,这是为了提高运行速度。
上例子中有他的用法。
int sqlite3_exec(
const char *sql,
int (*callback)(void*,int,char**,char**),
char **errmsg
其中callback的原型是:
sqlite3_exec
_callback(void
*data, int
n_columns, char
**col_values, char
**col_names);
sqlite3_exec()是对一些基本sqlite3的基本包装,它使用起来更方便。有个回调函数传给sqlite3_exec()是用来处理每一个行的结果。
int sqlite3_exec_callback(void *data, int n_columns, char **col_values, char **col_names)
printf("n_columns : %d/n",n_columns);
for (i = 0; i & n_ i++)
// printf("%s/t",col_names[i]);
printf("%s/t", col_values[i]);
printf("/n");
printf("%s/t", col_values[i]);
printf("%s/t", col_values[i+1]);
sqlite3_exec(db,sql,&sqlite3_exec_callback,0,&errmsg);
这个挺好用,当没有返回值时,这个很好用,不需要回调函数。
说明上是只能返回一行,实际试验也是,但是网上的说能返回所有的结果,不知道为什么。这个占时不会用。
sqlite3_get_table
这个函数是个旧的接口,不推荐使用,但是却很好使用。
int sqlite3_get_table(
sqlite3 *db,
const char *zSql,
char ***pazResult,
int *pnRow,
int *pnColumn,
char **pzErrmsg
void sqlite3_free_table(char **result);
这两个函数要成对的使用。
这是个就的接口函数,是不推荐用的,但是却很方便。
假设返回了N行M列,那么共有(N+1)*M元素。结果放在pazResult,其实
pazResult是个指针数组char **pazResult,
假设我们要查的表的结果如下,此时N==3
M=2,那么共有8个结果放在pazResult
-----------------------
指针数组pazResult存放的结果如下图:
每个指针放着每行的每个列的值
azResult[0] = "Name";
azResult[1] = "Age";
azResult[2] = "Alice";
azResult[3] = "43";
azResult[4] = "Bob";
azResult[5] = "28";
azResult[6] = "Cindy";
azResult[7] = "21";
当用完这个函数后,我们必须用sqlite3_free_table释放掉之前的内存。其实这个函数是
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。需要使用sqlite里的password对某个字段进行加密,由于使用的sqlite是由QT封装好的QSqlDatabase,没有发现加载扩展函数的方法,所以自己实现了一个。
在网上也没找到相应的参考,就自己查官方文档解决了。本篇文章主要是sqlite如何加载外部的函数,并没有password函数的实现,我将写好的函数生成了一个动态库,由程序动态加载。
#include &iostream&
#include &QString&
#include &QtSql/QSqlQuery&
#include &QtSql/QSqlDatabase&
#include &QtSql/QSqlQuery&
#include &QtSql/QSqlError&
#include &QtSql/QSqlDriver&
#include &QVariant&
#include &sqlite3.h&
#include &string.h&
void insert_database(QSqlDatabase& database,QString name)
QSqlQuery query(database);
if(!query.exec("insert into data(name) values(password('"+name+"') )"))
cout&&query.lastError().text().toStdString()&&std::
int main()
QSqlDatabase database=QSqlDatabase::addDatabase("QSQLITE");
database.setDatabaseName("data.db");
if(!database.open())
cout&&"open database failure"&&std::
QVariant handle=database.driver()-&handle();
if(!handle.isValid())
cout&&"handle not valid"&&
sqlite3* sqlhandle=*static_cast&sqlite3**&(handle.data());
char * error=(char*)sqlite3_malloc(1024);
sqlite3_enable_load_extension(sqlhandle,1);
if(SQLITE_OK==sqlite3_load_extension(sqlhandle,"/home/quanwei/desktop/my-documents/code/qt/loadsqlitefunction/password.so",0,&error));
cout&&"error: "&&error&&std::
sqlite3_free(error);
insert_database(database,"hello");
database.close();
数据库结构也放出来参考
CREATE TABLE data(id integer primary key,name text);
此程序用到的库的支持:QtCore,QtSql,sqlite3
具体接口官方文档有说明
Loading An Extension An SQLite extension is a shared library or DLL. To load it, you need to supply SQLite with the name of the file containing the shared library or DLL and an entry point to initialize the extension. In C code, this information is supplied using the sqlite3_load_extension() API. See the documentation on that routine for additional information. Note that different operating systems use different filename suffixes for their shared libraries. Windows use ".dll", Mac uses ".dylib", and most unixes other than mac use ".so". If you want to make your code portable, you can omit the suffix from the shared library filename and the appropriate suffix will be added automatically by the sqlite3_load_extension() interface.
不过由于默认load_extension是处于关闭状态,所以需要调用sqlite3_enable_load_extension打开扩展功能在sqlite3的shell里可以通过执行
sqlite3& .load ./password
来加载一个动态库函数,但是由于扩展函数没有储存在数据库中,所以每次打开这个数据库中都要加载一次才能使用自定义函数。
参考:https://www.sqlite.org/loadext.html
/qt%E5%AE%9E%E7%8E%B0-%E7%BB%99sqlite%E6%B7%BB%E5%8A%A0%E8%87%AA%E5%AE%9A%E4%B9%89%E5%87%BD%E6%95%B0/
Views(...) Comments()}

我要回帖

更多关于 sqlite3 函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信