sqlite之我见--C/C++ API接口示例 .
来源:互联网 发布:linux shell rm rf 编辑:程序博客网 时间:2024/06/15 09:52
在之前的两篇博文中,分别介绍了SQLITE的基础知识和操作,C/C++ 的一些常用API
sqlite之我见--简单介绍与基本操作
sqlite之我见--C/C++ API接口介绍
本文中,我会给大家用几个小程序示例SQLITE C/C++ API的使用。
1.我们看下最简单的sqlite程序,通过sqlite3_open, sqlite3_exec, sqlite3_close来实现一个简单的数据库操作。
- /*
- * File: sqlite_test.cpp
- * Author: Carl
- *
- * Created on September 20, 2012, 3:28 PM
- */
- #include <cstdlib>
- #include <cstdio>
- #include <sqlite3.h>
- static int _sql_callback(void *notused, int argc, char **argv, char **szColName)
- {
- int i = 0;
- printf("notused:0x%x, argc:%d\n", notused, argc);
- for (i = 0; i < argc; i++)
- {
- printf("%s = %s\n", szColName[i], argv[i] == 0 ? "NULL" : argv[i]);
- }
- printf("\n");
- return 0;
- }
- /*
- *
- */
- int main(int argc, char** argv)
- {
- const char *sSQL1 = "create table users(userid varchar(20) PRIMARY KEY, age int, birthday datetime);";
- const char *sSQL2 = "insert into users values('wang', 20, '1989-5-4');";
- const char *sSQL3 = "select * from users;";
- sqlite3 *db = 0;
- char *pErrMsg = 0;
- int ret = 0;
- //连接数据库
- ret = sqlite3_open("./test.db", &db);
- if (ret != SQLITE_OK)
- {
- fprintf(stderr, "无法打开数据库:%s\n", sqlite3_errmsg(db));
- sqlite3_close(db);
- return 1;
- }
- printf("数据库连接成功\n");
- //执行建表SQL
- ret = sqlite3_exec(db, sSQL1, _sql_callback, 0, &pErrMsg);
- if (ret != SQLITE_OK)
- {
- fprintf(stderr, "SQL create error: %s\n", pErrMsg);
- sqlite3_free(pErrMsg); //这个要的哦,要不然会内存泄露的哦!!!
- sqlite3_close(db);
- return 1;
- }
- printf("数据库建表成功!!\n");
- //执行插入数据
- ret = sqlite3_exec(db, sSQL2, _sql_callback, 0, &pErrMsg);
- if (ret != SQLITE_OK)
- {
- fprintf(stderr, "SQL insert error: %s\n", pErrMsg);
- sqlite3_free(pErrMsg); //这个要的哦,要不然会内存泄露的哦!!!
- sqlite3_close(db);
- return 1;
- }
- printf("数据库插入数据成功!\n");
- //执行查询操作
- ret = sqlite3_exec(db, sSQL3, _sql_callback, 0, &pErrMsg);
- if (ret != SQLITE_OK)
- {
- fprintf(stderr, "SQL error: %s\n", pErrMsg);
- sqlite3_free(pErrMsg);
- sqlite3_close(db);
- return 1;
- }
- printf("数据库查询成功!!\n");
- //关闭数据库
- sqlite3_close(db);
- db = 0;
- return 0;
- }
/* * File: sqlite_test.cpp * Author: Carl * * Created on September 20, 2012, 3:28 PM */#include <cstdlib>#include <cstdio>#include <sqlite3.h>static int _sql_callback(void *notused, int argc, char **argv, char **szColName){ int i = 0; printf("notused:0x%x, argc:%d\n", notused, argc); for (i = 0; i < argc; i++) { printf("%s = %s\n", szColName[i], argv[i] == 0 ? "NULL" : argv[i]); } printf("\n"); return 0;}/* * */int main(int argc, char** argv){ const char *sSQL1 = "create table users(userid varchar(20) PRIMARY KEY, age int, birthday datetime);"; const char *sSQL2 = "insert into users values('wang', 20, '1989-5-4');"; const char *sSQL3 = "select * from users;"; sqlite3 *db = 0; char *pErrMsg = 0; int ret = 0; //连接数据库 ret = sqlite3_open("./test.db", &db); if (ret != SQLITE_OK) { fprintf(stderr, "无法打开数据库:%s\n", sqlite3_errmsg(db)); sqlite3_close(db); return 1; } printf("数据库连接成功\n"); //执行建表SQL ret = sqlite3_exec(db, sSQL1, _sql_callback, 0, &pErrMsg); if (ret != SQLITE_OK) { fprintf(stderr, "SQL create error: %s\n", pErrMsg); sqlite3_free(pErrMsg); //这个要的哦,要不然会内存泄露的哦!!! sqlite3_close(db); return 1; } printf("数据库建表成功!!\n"); //执行插入数据 ret = sqlite3_exec(db, sSQL2, _sql_callback, 0, &pErrMsg); if (ret != SQLITE_OK) { fprintf(stderr, "SQL insert error: %s\n", pErrMsg); sqlite3_free(pErrMsg); //这个要的哦,要不然会内存泄露的哦!!! sqlite3_close(db); return 1; } printf("数据库插入数据成功!\n"); //执行查询操作 ret = sqlite3_exec(db, sSQL3, _sql_callback, 0, &pErrMsg); if (ret != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", pErrMsg); sqlite3_free(pErrMsg); sqlite3_close(db); return 1; } printf("数据库查询成功!!\n"); //关闭数据库 sqlite3_close(db); db = 0; return 0;}
运行结果如下结果:
- [carl@Fedora sqlite]$ g++ sqlite_test.cpp -lsqlite3
- [carl@Fedora sqlite]$ ./a.out
- 数据库连接成功
- 数据库建表成功!!
- 数据库插入数据成功!
- notused:0x0, argc:3
- userid = wang
- age = 20
- birthday = 1989-5-4
- 数据库查询成功!!
- [carl@Fedora sqlite]$
[carl@Fedora sqlite]$ g++ sqlite_test.cpp -lsqlite3[carl@Fedora sqlite]$ ./a.out 数据库连接成功数据库建表成功!!数据库插入数据成功!notused:0x0, argc:3userid = wangage = 20birthday = 1989-5-4数据库查询成功!![carl@Fedora sqlite]$
2. 我们再看一个在sqlite上是有事务来实现原子操作的的例子,
代码如下:
- /*
- * File: sqlite_test.cpp
- * Author: Carl
- *
- * Created on 2012年9月22日, 上午7:50
- */
- #include <cstdlib>
- #include <cstdio>
- #include <sqlite3.h>
- static int _sql_callback(void *notused, int argc, char **argv, char **szColName)
- {
- int i = 0;
- printf("notused:0x%x, argc:%d\n", notused, argc);
- for (i = 0; i < argc; i++)
- {
- printf("%s = %s\n", szColName[i], argv[i] == 0 ? "NULL" : argv[i]);
- }
- printf("\n");
- return 0;
- }
- /*
- *
- */
- int main(int argc, char** argv)
- {
- const char *sSQL1 = "create table test_for_cpp (id int, name varchar(10), age int);";
- char sql[100] = {0};
- sqlite3 *db = NULL;
- char *pErrMsg = NULL;
- int ret = 0;
- bool is_success = true;
- const char *sSQL3 = "select * from test_for_cpp;";
- ret = sqlite3_open("./test.db", &db);
- if (SQLITE_OK != ret)
- {
- fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
- sqlite3_close(db);
- return 1;
- }
- printf("数据库连接成功\n");
- ret = sqlite3_exec(db, sSQL1, NULL, 0, &pErrMsg);
- if (SQLITE_OK != ret)
- {
- fprintf(stderr, "SQL create error: %s\n", pErrMsg);
- sqlite3_free(pErrMsg);
- sqlite3_close(db);
- return 1;
- }
- printf("数据库建表成功!!\n");
- sqlite3_exec(db, "begin;", _sql_callback, 0, &pErrMsg); //开启事务
- if (SQLITE_OK != ret)
- {
- fprintf(stderr, "SQL begin error: %s\n", pErrMsg);
- sqlite3_free(pErrMsg);
- sqlite3_close(db);
- return 1;
- }
- printf("数据库开启事务成功!!\n");
- for (int i = 0; i < 10; i++)
- {
- sprintf(sql, "insert into test_for_cpp(id, name, age) values(%d, \"%s\", %d);", i, "Carl", i);
- ret = sqlite3_exec(db, sql, _sql_callback, 0, &pErrMsg);
- if (SQLITE_OK != ret)
- {
- is_success = false;
- fprintf(stderr, "for %d time error: %s\n", i, pErrMsg);
- sqlite3_free(pErrMsg);
- break;
- }
- }
- if (is_success)
- {
- sqlite3_exec(db, "commit;", 0, 0, 0);
- printf("数据库插入数据成功!\n");
- }
- else
- {
- sqlite3_exec(db, "rollback;", 0, 0, 0);
- printf("数据库插入数据失败!\n");
- }
- ret = sqlite3_exec(db, sSQL3, _sql_callback, 0, &pErrMsg);
- if (SQLITE_OK != ret)
- {
- fprintf(stderr, "SQL ERROR: %s\n", pErrMsg);
- sqlite3_free(pErrMsg);
- sqlite3_close(db);
- return 1;
- }
- printf("数据库查询成功!!\n");
- sqlite3_close(db);
- db = 0;
- return 0;
- }
/* * File: sqlite_test.cpp * Author: Carl * * Created on 2012年9月22日, 上午7:50 */#include <cstdlib>#include <cstdio>#include <sqlite3.h>static int _sql_callback(void *notused, int argc, char **argv, char **szColName){ int i = 0; printf("notused:0x%x, argc:%d\n", notused, argc); for (i = 0; i < argc; i++) { printf("%s = %s\n", szColName[i], argv[i] == 0 ? "NULL" : argv[i]); } printf("\n"); return 0;}/* * */int main(int argc, char** argv){ const char *sSQL1 = "create table test_for_cpp (id int, name varchar(10), age int);"; char sql[100] = {0}; sqlite3 *db = NULL; char *pErrMsg = NULL; int ret = 0; bool is_success = true; const char *sSQL3 = "select * from test_for_cpp;"; ret = sqlite3_open("./test.db", &db); if (SQLITE_OK != ret) { fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return 1; } printf("数据库连接成功\n"); ret = sqlite3_exec(db, sSQL1, NULL, 0, &pErrMsg); if (SQLITE_OK != ret) { fprintf(stderr, "SQL create error: %s\n", pErrMsg); sqlite3_free(pErrMsg); sqlite3_close(db); return 1; } printf("数据库建表成功!!\n"); sqlite3_exec(db, "begin;", _sql_callback, 0, &pErrMsg); //开启事务 if (SQLITE_OK != ret) { fprintf(stderr, "SQL begin error: %s\n", pErrMsg); sqlite3_free(pErrMsg); sqlite3_close(db); return 1; } printf("数据库开启事务成功!!\n"); for (int i = 0; i < 10; i++) { sprintf(sql, "insert into test_for_cpp(id, name, age) values(%d, \"%s\", %d);", i, "Carl", i); ret = sqlite3_exec(db, sql, _sql_callback, 0, &pErrMsg); if (SQLITE_OK != ret) { is_success = false; fprintf(stderr, "for %d time error: %s\n", i, pErrMsg); sqlite3_free(pErrMsg); break; } } if (is_success) { sqlite3_exec(db, "commit;", 0, 0, 0); printf("数据库插入数据成功!\n"); } else { sqlite3_exec(db, "rollback;", 0, 0, 0); printf("数据库插入数据失败!\n"); } ret = sqlite3_exec(db, sSQL3, _sql_callback, 0, &pErrMsg); if (SQLITE_OK != ret) { fprintf(stderr, "SQL ERROR: %s\n", pErrMsg); sqlite3_free(pErrMsg); sqlite3_close(db); return 1; } printf("数据库查询成功!!\n"); sqlite3_close(db); db = 0; return 0;}
运行结果:
- [carl@Fedora sqlite]$ g++ sqlite_test.cpp -lsqlite3
- [carl@Fedora sqlite]$ ./a.out
- 数据库连接成功
- 数据库建表成功!!
- 数据库开启事务成功!!
- 数据库插入数据成功!
- notused:0x0, argc:3
- id = 0
- name = Carl
- age = 0
- notused:0x0, argc:3
- id = 1
- name = Carl
- age = 1
- notused:0x0, argc:3
- id = 2
- name = Carl
- age = 2
- notused:0x0, argc:3
- id = 3
- name = Carl
- age = 3
- notused:0x0, argc:3
- id = 4
- name = Carl
- age = 4
- notused:0x0, argc:3
- id = 5
- name = Carl
- age = 5
- notused:0x0, argc:3
- id = 6
- name = Carl
- age = 6
- notused:0x0, argc:3
- id = 7
- name = Carl
- age = 7
- notused:0x0, argc:3
- id = 8
- name = Carl
- age = 8
- notused:0x0, argc:3
- id = 9
- name = Carl
- age = 9
- 数据库查询成功!!
- [carl@Fedora sqlite]$
[carl@Fedora sqlite]$ g++ sqlite_test.cpp -lsqlite3[carl@Fedora sqlite]$ ./a.out 数据库连接成功数据库建表成功!!数据库开启事务成功!!数据库插入数据成功!notused:0x0, argc:3id = 0name = Carlage = 0notused:0x0, argc:3id = 1name = Carlage = 1notused:0x0, argc:3id = 2name = Carlage = 2notused:0x0, argc:3id = 3name = Carlage = 3notused:0x0, argc:3id = 4name = Carlage = 4notused:0x0, argc:3id = 5name = Carlage = 5notused:0x0, argc:3id = 6name = Carlage = 6notused:0x0, argc:3id = 7name = Carlage = 7notused:0x0, argc:3id = 8name = Carlage = 8notused:0x0, argc:3id = 9name = Carlage = 9数据库查询成功!![carl@Fedora sqlite]$
3. 我们接着看一下如何能够更好的使用语句参数来操作sqlite数据库,用sqlite3_prepare_v2, sqlite3_bind_*, sqlite3_step, sqlite3_column_*等接口来实现对数据库的操作。
代码如下:里面的注释,有兴趣的可以试着打开试一下,但要记得注释掉相关的重复功能的语句哦。
- /*
- * File: sqlite_test2.cpp
- * Author: Carl
- *
- * Created on September 21, 2012, 3:12 PM
- */
- #include <cstdlib>
- #include <cstdio>
- #include <cstring>
- #include <sqlite3.h>
- static int _sql_callback(void *notused, int argc, char **argv, char **szColName)
- {
- int i = 0;
- printf("notused:0x%x, argc:%d\n", notused, argc);
- for (i = 0; i < argc; i++)
- {
- printf("%s = %s\n", szColName[i], argv[i] == 0 ? "NULL" : argv[i]);
- }
- printf("\n");
- return 0;
- }
- /*
- *
- */
- int main(int argc, char** argv)
- {
- sqlite3 *conn = NULL;
- sqlite3_stmt *stmt = NULL;
- char *err_msg = NULL;
- int ret = 0;
- char col_types[][10] = {"", "Interger", "Float", "Text", "Blob", "NULL"};
- ret = sqlite3_open("./test.db", &conn);
- if (SQLITE_OK != ret)
- {
- fprintf(stderr, "sqlite open err, %d\n", ret);
- return 1;
- }
- printf("打开数据库成功!!!\n");
- // ret = sqlite3_prepare_v2(conn, "SELECT * FROM [test_for_cpp] WHERE [name]==:name", -1, &stmt, (const char **)&err_msg);
- ret = sqlite3_prepare_v2(conn, "SELECT * FROM [test_for_cpp] WHERE [name]==?2", -1, &stmt, (const char **)&err_msg);
- if (SQLITE_OK != ret)
- {
- fprintf(stderr, "sqlite prepare error: %s\n", err_msg);
- sqlite3_free(err_msg);
- sqlite3_close(conn);
- return 1;
- }
- // printf("数据库语句对象编译成功!!!%d\n", sqlite3_bind_parameter_index(stmt, ":name"));
- printf("数据库语句对象编译成功!!!\n");
- ret = sqlite3_bind_text(stmt, 2, "Carl", 4, SQLITE_STATIC);
- if (SQLITE_OK != ret)
- {
- fprintf(stderr, "sqlite bind error: %d\n", ret);
- sqlite3_close(conn);
- return 1;
- }
- printf("数据库语句对象bind成功!!!\n");
- while (ret = sqlite3_step(stmt), ret == SQLITE_ROW)
- {
- int col_count = sqlite3_column_count(stmt); //结果集中列的数量
- printf("列数:%d\t", col_count);
- const char *col_0_name = sqlite3_column_name(stmt, 0); //获取列名
- printf("列名:%s\t", col_0_name);
- int id = sqlite3_column_int(stmt, 0);
- printf("id值:%d\t", id);
- int id_type = sqlite3_column_type(stmt, 0); //获取列数据类型
- printf("id类型:%d\t", id_type);
- const char *col_2_name = sqlite3_column_name(stmt, 2);
- int age = sqlite3_column_int(stmt, 2);
- int age_type = sqlite3_column_type(stmt, 2);
- const char *col_1_name = sqlite3_column_name(stmt, 1);
- char name[80];
- strncpy(name, (const char *)sqlite3_column_text(stmt, 1), 80);
- int name_type = sqlite3_column_type(stmt, 1);
- //打印结果
- printf("col_count: %d, %s = %d(%s), %s = %s(%s), %s = %d(%s)\n",
- col_count, col_0_name, id, col_types[id_type], col_1_name, name,
- col_types[name_type], col_2_name, age, col_types[age_type]);
- }
- fprintf(stderr, "sqlite step exit with %d\n", ret);
- sqlite3_finalize(stmt);
- sqlite3_close(conn);
- return 0;
- }
/* * File: sqlite_test2.cpp * Author: Carl * * Created on September 21, 2012, 3:12 PM */#include <cstdlib>#include <cstdio>#include <cstring>#include <sqlite3.h>static int _sql_callback(void *notused, int argc, char **argv, char **szColName){ int i = 0; printf("notused:0x%x, argc:%d\n", notused, argc); for (i = 0; i < argc; i++) { printf("%s = %s\n", szColName[i], argv[i] == 0 ? "NULL" : argv[i]); } printf("\n"); return 0;}/* * */int main(int argc, char** argv){ sqlite3 *conn = NULL; sqlite3_stmt *stmt = NULL; char *err_msg = NULL; int ret = 0; char col_types[][10] = {"", "Interger", "Float", "Text", "Blob", "NULL"}; ret = sqlite3_open("./test.db", &conn); if (SQLITE_OK != ret) { fprintf(stderr, "sqlite open err, %d\n", ret); return 1; } printf("打开数据库成功!!!\n"); // ret = sqlite3_prepare_v2(conn, "SELECT * FROM [test_for_cpp] WHERE [name]==:name", -1, &stmt, (const char **)&err_msg); ret = sqlite3_prepare_v2(conn, "SELECT * FROM [test_for_cpp] WHERE [name]==?2", -1, &stmt, (const char **)&err_msg); if (SQLITE_OK != ret) { fprintf(stderr, "sqlite prepare error: %s\n", err_msg); sqlite3_free(err_msg); sqlite3_close(conn); return 1; }// printf("数据库语句对象编译成功!!!%d\n", sqlite3_bind_parameter_index(stmt, ":name")); printf("数据库语句对象编译成功!!!\n"); ret = sqlite3_bind_text(stmt, 2, "Carl", 4, SQLITE_STATIC); if (SQLITE_OK != ret) { fprintf(stderr, "sqlite bind error: %d\n", ret); sqlite3_close(conn); return 1; } printf("数据库语句对象bind成功!!!\n"); while (ret = sqlite3_step(stmt), ret == SQLITE_ROW) { int col_count = sqlite3_column_count(stmt); //结果集中列的数量 printf("列数:%d\t", col_count); const char *col_0_name = sqlite3_column_name(stmt, 0); //获取列名 printf("列名:%s\t", col_0_name); int id = sqlite3_column_int(stmt, 0); printf("id值:%d\t", id); int id_type = sqlite3_column_type(stmt, 0); //获取列数据类型 printf("id类型:%d\t", id_type); const char *col_2_name = sqlite3_column_name(stmt, 2); int age = sqlite3_column_int(stmt, 2); int age_type = sqlite3_column_type(stmt, 2); const char *col_1_name = sqlite3_column_name(stmt, 1); char name[80]; strncpy(name, (const char *)sqlite3_column_text(stmt, 1), 80); int name_type = sqlite3_column_type(stmt, 1); //打印结果 printf("col_count: %d, %s = %d(%s), %s = %s(%s), %s = %d(%s)\n", col_count, col_0_name, id, col_types[id_type], col_1_name, name, col_types[name_type], col_2_name, age, col_types[age_type]); } fprintf(stderr, "sqlite step exit with %d\n", ret); sqlite3_finalize(stmt); sqlite3_close(conn); return 0;}
运行结果如下:
- [carl@Fedora sqlite]$ g++ sqlite_test2.cpp -lsqlite3
- [carl@Fedora sqlite]$ ./a.out
- 打开数据库成功!!!
- 数据库语句对象编译成功!!!
- 数据库语句对象bind成功!!!
- 列数:3 列名:id id值:0 id类型:1 col_count: 3, id = 0(Interger), name = Carl(Text), age = 0(Interger)
- 列数:3 列名:id id值:1 id类型:1 col_count: 3, id = 1(Interger), name = Carl(Text), age = 1(Interger)
- 列数:3 列名:id id值:2 id类型:1 col_count: 3, id = 2(Interger), name = Carl(Text), age = 2(Interger)
- 列数:3 列名:id id值:3 id类型:1 col_count: 3, id = 3(Interger), name = Carl(Text), age = 3(Interger)
- 列数:3 列名:id id值:4 id类型:1 col_count: 3, id = 4(Interger), name = Carl(Text), age = 4(Interger)
- 列数:3 列名:id id值:5 id类型:1 col_count: 3, id = 5(Interger), name = Carl(Text), age = 5(Interger)
- 列数:3 列名:id id值:6 id类型:1 col_count: 3, id = 6(Interger), name = Carl(Text), age = 6(Interger)
- 列数:3 列名:id id值:7 id类型:1 col_count: 3, id = 7(Interger), name = Carl(Text), age = 7(Interger)
- 列数:3 列名:id id值:8 id类型:1 col_count: 3, id = 8(Interger), name = Carl(Text), age = 8(Interger)
- 列数:3 列名:id id值:9 id类型:1 col_count: 3, id = 9(Interger), name = Carl(Text), age = 9(Interger)
- sqlite step exit with 101 //101意思为SQLITE_DONE
- [carl@Fedora sqlite]$
[carl@Fedora sqlite]$ g++ sqlite_test2.cpp -lsqlite3[carl@Fedora sqlite]$ ./a.out 打开数据库成功!!!数据库语句对象编译成功!!!数据库语句对象bind成功!!!列数:3列名:idid值:0id类型:1col_count: 3, id = 0(Interger), name = Carl(Text), age = 0(Interger)列数:3列名:idid值:1id类型:1col_count: 3, id = 1(Interger), name = Carl(Text), age = 1(Interger)列数:3列名:idid值:2id类型:1col_count: 3, id = 2(Interger), name = Carl(Text), age = 2(Interger)列数:3列名:idid值:3id类型:1col_count: 3, id = 3(Interger), name = Carl(Text), age = 3(Interger)列数:3列名:idid值:4id类型:1col_count: 3, id = 4(Interger), name = Carl(Text), age = 4(Interger)列数:3列名:idid值:5id类型:1col_count: 3, id = 5(Interger), name = Carl(Text), age = 5(Interger)列数:3列名:idid值:6id类型:1col_count: 3, id = 6(Interger), name = Carl(Text), age = 6(Interger)列数:3列名:idid值:7id类型:1col_count: 3, id = 7(Interger), name = Carl(Text), age = 7(Interger)列数:3列名:idid值:8id类型:1col_count: 3, id = 8(Interger), name = Carl(Text), age = 8(Interger)列数:3列名:idid值:9id类型:1col_count: 3, id = 9(Interger), name = Carl(Text), age = 9(Interger)sqlite step exit with 101 //101意思为SQLITE_DONE[carl@Fedora sqlite]$
下面解释下为什么要学会这种能够细致控制sqlite的方法(即使用语句参数),主要有以下几个优点:
(1) 使用“语句参数”方式,具有更高的安全性,可以有效防止“SQL注入攻击”。 “SQL注入攻击”要想达到目的,就必须让attack value随着SQL命令字符串一起传送进SQL解析器。黑客如果在一条SQL命令字符串被送入到sqlite3_prepare函数之前,利用c字符串处理函数等途径将attack value注入其中,而在sqlite3_prepare函数之中进行解析(parse),就可以达到攻击目的。而使用“语句参数”方式,被传送到sqlite3_prepare函数的只是SQL命令字符串中的参数符号(如:“?”),而不是具体的值。在sqlite3_prepare函数执行之后,才会使用bind函数给参数符号绑定具体的值,这就可以避免attack value随着SQL命令字符串一起在sqlite3_prepare函数中被解析,从而有效躲避“SQL注入攻击”。
(2)使用“语句参数”方式,可以更快的完成值替换。
(3)使用“语句参数”方式,更节省内存。原因是使用如snprintf函数,需要一个SQL命令模板,一块足够大的输出缓存,而且字符串处理函数需要工作内存(working memory),除此之外对于整形,浮点型,特别是BLOBs,经常会占用更多的空间。
- sqlite之我见--C/C++ API接口示例
- sqlite之我见--C/C++ API接口示例 .
- sqlite之我见--C/C++ API接口示例 --回调 事务
- sqlite之我见--C/C++ API接口示例
- sqlite之我见--C/C++ API接口介绍
- sqlite之我见--C/C++ API接口介绍 .
- sqlite API(C\C++)接口示例
- SQLite入门(一) 之 C/C++ 接口 API
- sqlite C/C++ API接口介绍
- sqlite C/C++ API接口介绍
- c++/cli之我见
- 【C#】c#之我见
- sqlite-sqlite接口-C/C++
- sqlite C/C++ API
- SQLite C语言接口
- SQLite C语言接口
- SQLite C/C++接口
- 智能手表开发API接口之我见
- elasticsearch安装配置
- POJ 1564 Sum It Up
- 习惯
- SpringMVC+Quartz配置定时任务
- 浅谈EasyUI的使用
- sqlite之我见--C/C++ API接口示例 .
- 基于Local Search的直线匹配算法
- jquery对信息进行排序操作
- 物联网15年,盘点国内崛起的智能产业
- 四翼---MPU6050
- hibernate.cfg.xml文件详解
- php利用ajax双击table修改内容
- 危险的房屋拆改情况
- [2012山东省第三届ACM大学生程序设计竞赛]——Mine Number